sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL-implementatie en onderhoud met Ansible

Ansible is een van de meest bekende en meest gebruikte IT-automatiseringstools, het helpt ons bij het automatiseren van operationele IT-taken zoals...

  • De host (VM of bare-metal machine) helemaal opnieuw opstarten
  • Hosts en services configureren
  • Software-implementaties en upgrades beheren
  • Ansible biedt ook ondersteuning voor het orkestreren van de cloudinfrastructuur, zoals het maken van een aantal EC2- en RDS-instanties voor uw toepassingen op openbare clouds (AWS, GCP, Azure). Meer over de cloud-provisioning vindt u hier

Aangezien deze blog vooral gaat over het beheren van PostgreSQL met behulp van Ansible, zullen we niet in detail treden over het gebruik van Ansible, maar we zullen enkele basisprincipes van Ansible doornemen. Ik raad aan om de Ansible-documentlink te gebruiken als je er meer over wilt weten.

Basisprincipes van Ansible

Ansible is een open-sourceproject geschreven in python waarvan de broncode beschikbaar is op GitHub. Omdat het een python-pakket is, kunnen we Ansible eenvoudig installeren met pip.

Ansible hoeft slechts op één host te worden geïnstalleerd van waaruit we onze operationele taken zullen orkestreren met behulp van Ansible-opdrachten (Ansible, Ansible-playbook). We noemen deze orkestratiehost de Control Node.

Ansible-opdrachten gebruiken OpenSSH-bibliotheken om in te loggen op de doelhosts voor het uitvoeren van operationele taken, we noemen deze doelhosts Managed Node. De hostnaam of het IP-adres van de Managed Node wordt vermeld in een bestand dat Inventory wordt genoemd. Deze bestandsnaam van de inventaris wordt vervolgens gespecificeerd als invoer voor de Ansible-opdrachten.

In het inventarisbestand kunnen we meerdere hosts onder één enkele groep vermelden, dit voorkomt dat dezelfde taken meerdere keren worden herhaald voor verschillende hosts. Meer details over het gebruik van inventarisbestanden vindt u hier.

Aangezien de Ansible-opdracht SSH gebruikt om in te loggen, is het niet nodig om Ansible op alle hosts te installeren, het hoeft alleen op de Control Node te worden geïnstalleerd. Op alle Control Node en Managed Node moeten echter python en alle benodigde python-bibliotheken zijn geïnstalleerd. Meer over de Ansible-installatie vindt u hier.

Voor de demo gebruik ik een laptop als het controleknooppunt en gast CentOS-7 VM als het beheerde knooppunt. De CentOS-7 VM is ingericht met Vagrant op de provider VirtualBox.

Ansible installeren op de Control Node

We zullen Ansible installeren met pip zoals vermeld op de Ansible-documentpagina. De volgende commando's zijn uitgevoerd als "Ansible" gebruiker.

$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user

Door de optie --user te gebruiken, worden pip- en Ansible-opdrachten geïnstalleerd onder de HOME-directory en moeten we het bin-pad toevoegen aan onze PATH-omgevingsvariabele.

$ echo 'export PATH=$HOME/Library/Python/2.7/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile

Met het volgende pip-commando is Ansible-versie 2.8.0 geïnstalleerd (de nieuwste stabiele versie op het moment van schrijven van deze blog.)

$ pip install --user ansible 
$ which ansible
/Users/Ansible/Library/Python/2.7/bin/Ansible
$ ansible --version
Ansible 2.8.0
...
... 

Control Node en Managed Node Prechecks

Zorg voor een goede netwerkverbinding tussen het controleknooppunt en het beheerde knooppunt.

Controleer uw firewall op regels die inkomende en uitgaande verbindingen op de SSH-poort kunnen blokkeren. Als dit het geval is, open dan de SSH-poort om toegang te verlenen op zowel de controle- als de beheerde nodes.

Probeer eerst via SSH verbinding te maken met het beheerde knooppunt. U zou in staat moeten zijn om in te loggen op het beheerde knooppunt vanaf het controleknooppunt.

U kunt de wachtwoordloze SSH-toegang tot de beheerde knooppunten instellen volgens het beveiligingsbeleid van uw organisatie. Voor deze demo heb ik wachtwoordloos geconfigureerd voor SSH naar mijn beheerde node "pg01" (CentOS-7) voor de gebruiker "zwerver". Dit zorgt ervoor dat het beheerde knooppunt de sudo-kracht heeft, de meeste installatie- en hostconfiguratietaken worden uitgevoerd als een "zwervende" gebruiker met "sudo".

Op het besturingsknooppunt hebben we het configuratiebestand ansible.cfg dat zal worden gebruikt door de Ansible-opdrachten. Hieronder staan ​​enkele configuratie-opties die zijn gedefinieerd in het configuratiebestand. Bekijk het voorbeeldconfiguratiebestand voor meer informatie over de andere beschikbare configuratieopties.

  • remote_port - Als de SSH-server op het beheerde knooppunt op een andere poort dan de standaardpoort 22 draait, kunnen we deze wijzigen
  • remote_user - De login gebruikersnaam die door Ansible zal worden gebruikt om het beheerde knooppunt te verbinden, voor het uitvoeren van de taken
  • private_key_file - SSH-privésleutel die zal worden gebruikt om Ansible in te loggen

Aangezien de bovengenoemde configuratie globaal van toepassing is op alle beheerde knooppunten, kunnen we deze specificeren in het inventarisbestand als we een andere configuratie willen hebben voor een specifieke host of hostgroep. Een voorbeeld hiervan ziet u hieronder in het inventarisbestand "development.yaml".

Een Ansible Dry Run uitvoeren

Maak een inventarisbestand “development.yaml” aan zoals hieronder getoond.

$ pwd
/Users/Ansible/postgres-setup

$ cat development.yaml 
all:
  hosts:
  children:
    postgres_clusters:
      hosts:
        pg01:
      vars: 
        ansible_port: 22
        ansible_user: "vagrant"
        ansible_private_key_file: "/Users/Ansible/postgres-setup/private_key"

In het bovenstaande inventarisatiebestand is host pg01 een van de leden van de hostgroep postgres_clusters. De variabelen ansible_port, ansible_user en ansible_private_key_file zijn alleen van toepassing op de hosts onder de groep postgres_clusters.

We gaan nu controleren of Ansible de taken op het beheerde knooppunt kan uitvoeren. In het onderstaande voorbeeld voert het ansible-commando de module-ping uit op het beheerde knooppunt pg01. Als Ansible de module-ping kon uitvoeren, zou u SUCCESS als antwoord moeten zien.

$ ansible -i development.yaml -m ping pg01
pg01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Bij het uitvoeren van Ansible op het beheerde knooppunt als de eerste taak, verzamelt het de informatie zoals hostnaam, IP-adres, het geheugen van het beheerde knooppunt. Om deze te controleren, kunnen we de module-setup bellen die een grote JSON zou retourneren. We kunnen deze allemaal gebruiken in ons Ansible-playbook.

$ ansible -i development.yaml -m setup pg01 
pg01 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.100.4", 
            "10.0.2.15"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::a00:27ff:fe29:ac89", 
            "fe80::5054:ff:fe26:1060"
        ],

Ansible-rol

Ansible Role is een manier om een ​​bepaalde reeks gerelateerde taken en configuratie-instellingen te bundelen in één enkele eenheid door een rol toe te wijzen aan een bepaalde host of hostgroep. Ansible zal alle gerelateerde configuraties en taken toepassen. Dit voorkomt dat de taken meerdere keren worden herhaald voor elke verschillende host of hostgroep.

Elke rol wordt weergegeven als een map en binnen de rolmap zijn er submappen zoals standaardbestanden, handlers, meta, taken, sjablonen, tests, vars. Het doel van deze mappen is hier te vinden.

Ansible-opdrachten doorzoeken standaard de roldirectory onder de paden die worden genoemd in DEFAULT_ROLES_PATH.

$ ansible-config list | grep -A2 '^DEFAULT_ROLES_PATH'
DEFAULT_ROLES_PATH:
  default: ~/.Ansible/roles:/usr/share/Ansible/roles:/etc/Ansible/roles
  description: Colon separated paths in which Ansible will search for Roles.

Ansible Galaxy

Ansible Galaxy is een portal waar de communityleden de GitHub-repository van hun Ansible-rollen delen. We kunnen door de galaxy-portal bladeren voor de vereiste Ansible-rollen. Met behulp van het commando ansible-galaxy konden we de rol downloaden en opnieuw gebruiken. Voordat u een rol gebruikt, moet u alle Ansible YAML-bestanden in detail doornemen onder de directory's standaardinstellingen, vars, taken, sjablonen, handlers en weet u hoe de rol werkt.

Voor onze implementatie van PostgreSQL zullen we de rol "postgresql" gebruiken die is ontwikkeld door de auteur ANXS en GitHub-repo.

Ansible-rol "anxs.postgresql" installeren

$ ansible-galaxy  install anxs.postgresql
- downloading role 'postgresql', owned by anxs
- downloading role from https://github.com/ANXS/postgresql/archive/v1.10.1.tar.gz
- extracting anxs.postgresql to /Users/ansible/.Ansible/roles/anxs.postgresql
- anxs.postgresql (v1.10.1) was installed successfully

Het bovenstaande commando installeert de rollenmap "anxs.postgresql" onder de map "/Users/ansible/.Ansible/roles", dit is een van de mappen in het DEFAULT_ROLES_PATH en het ansible-commando zoekt in deze map naar alle rollen.

Ansible Playbook

Een Ansible Playbook is een YAML-bestand waarin we de taken of rollen opsommen die op een bepaalde host of de hostgroep moeten worden uitgevoerd. Je kunt hier meer lezen over het ontwikkelen van playbooks en de definitie van tags zoals hosts, taken, rollen, vars leren.

Standaard worden alle taken uitgevoerd als de ansible gebruiker die is ingelogd. Om bepaalde taken uit te voeren met een andere gebruiker (of met ‘root’ privilege) kunnen we gebruik maken van word. Hoe u deze opdracht kunt gebruiken, vindt u hier.

In het onderstaande playbook (postgres-play.yaml), heb ik de rol "anxs.postgresql" vermeld onder de hostgroep "postgres_clusters", zodat alle taken in de rol anxs.postgresql worden uitgevoerd voor alle hosts onder de groep "postgres_clusters".

$ cat postgres-play.yaml 
---
- hosts: postgres_clusters
  become: yes
  roles: 
    - role: anxs.postgresql

worden:ja in de YAML definieert dat deze rol zal worden uitgevoerd met hogere bevoegdheden door gebruik te maken van de DEFAULT_BECOME_METHOD "sudo"

$ ansible-config list | grep -A2 '^DEFAULT_BECOME_METHOD'
DEFAULT_BECOME_METHOD:
  default: sudo
  description: Privilege escalation method to use when `become` is enabled.

We zullen dit playbook uitvoeren als de gebruiker "zwerver" en de gebruiker was al voorzien van sudo-power.

[[email protected] ~]$ sudo cat /etc/sudoers.d/vagrant
%vagrant ALL=(ALL) NOPASSWD: ALL
DevOps-gids voor databasebeheer van verschillendenines Lees meer over wat u moet weten om uw open source-databases te automatiseren en beherenGratis downloaden

PostgreSQL implementeren met Ansible

We zullen nu het playbook 'postgres-play.yaml' uitvoeren, dat alle PostgreSQL-gerelateerde pakketten zal installeren en configureren met de standaardinstellingen.

Voor dit voorbeeld installeert Ansible PostgreSQL 9.6 op poort 5432, met de postgres max_connections ingesteld op 100. Alle standaardinstellingen zijn te vinden in het bestand /Users/ansible/.Ansible/roles/anxs.postgresql/defaults/main.yml .

$ grep -E '^postgresql_(version|port|max_connections):' ~/.Ansible/roles/anxs.postgresql/defaults/main.yml 
postgresql_version: 9.6
postgresql_port: 5432
postgresql_max_connections: 100

Het draaiboek gebruiken

$ ansible-playbook -i development.yaml postgres-play.yaml
PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...


PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=21   changed=14   unreachable=0    failed=0    skipped=32   rescued=0    ignored=0 

Zodra de Ansible alle taken heeft uitgevoerd, wordt een samenvatting van de taakuitvoeringen getoond onder PLAY RECAP.

  • ok=21, 21 taken uitgevoerd zonder wijzigingen.
  • changed=14, 14 taken hebben wijzigingen aangebracht in de host, zoals het installeren van postgres, het maken van mappen, bestanden, het starten van de postgres.
  • skiped=32, 32 taken zijn overgeslagen, mogelijk omdat een bepaalde functie niet is ingeschakeld. Omdat we op entOS installeren, werden Ubuntu-gerelateerde taken overgeslagen.

Controleer de status en configuratie van de PostgreSQL-service.

[[email protected] ~]$ systemctl status postgresql-9.6
● postgresql-9.6.service - PostgreSQL 9.6 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-9.6.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/postgresql-9.6.service.d
           └─custom.conf
   Active: active (running) since Wed 2019-05-29 07:15:25 UTC; 24min ago
     Docs: https://www.postgresql.org/docs/9.6/static/
  Process: 7559 ExecStartPre=/usr/pgsql-9.6/bin/postgresql96-check-db-dir /var/lib/pgsql/9.6/data (code=exited, status=0/SUCCESS)
 Main PID: 7564 (postmaster)
   CGroup: /system.slice/postgresql-9.6.service
           ├─7564 /usr/pgsql-9.6/bin/postmaster -D /etc/postgresql/9.6/data
           ├─7567 postgres: checkpointer process   
           ├─7568 postgres: writer process   
           ├─7569 postgres: wal writer process   
           ├─7570 postgres: autovacuum launcher process   
           └─7571 postgres: stats collector process   

[[email protected] ~]$ psql -U postgres
psql (9.6.13)
Type "help" for help.

postgres=# show max_connections ;
 max_connections 
-----------------
 100
(1 row)

postgres=# show statement_timeout ;
 statement_timeout 
-------------------
 
(1 row)

postgres=# show log_min_duration_statement ;
 log_min_duration_statement 
----------------------------
 -1
(1 row)

We hebben nu PostgreSQL geïnstalleerd op de beheerde host "pg01" met behulp van de standaardconfiguratie.

De PostgreSQL-configuratie wijzigen

Nu gaan we de PostgreSQL-instantie opnieuw configureren met onze aangepaste instellingen.

Ik heb een custom.yaml-bestand gemaakt (zoals hieronder weergegeven) met de lijst met variabelen die zijn gedefinieerd om PostgreSQL-instellingen zoals listen_addresses, max_connections, wal_level, hot_standby, statement_timeout, log_checkpoint, log_lock_waits, log_destination, log_min_duration_statement.

$ pwd
/Users/ansible/postgres-setup
$ cat custom.yaml 
postgresql_listen_addresses: "*"
postgresql_max_connections: 300
postgresql_wal_level: "hot_standby"
postgresql_hot_standby: "on"
postgresql_statement_timeout: 60000
postgresql_log_lock_waits: "on"
postgresql_log_destination: "csvlog"
postgresql_log_min_duration_statement: 0

We zullen nu ons playbook postgres-play.yaml wijzigen om deze custom.yaml te gebruiken.

$ cat postgres-play.yaml  
---
- hosts: postgres_clusters
  become: yes
  vars_files:
    - ./custom.yaml
  roles: 
    - role: anxs.postgresql

Met behulp van vars_files-tags heb ik het aangepaste configuratiebestand custom.yaml gespecificeerd, dat de standaardconfiguratie die is opgegeven in de rol anxs.postgresql zal overschrijven. Meer details over de prioriteit van variabelen vindt u hier.

We kunnen nu dezelfde ansible-playbook-opdracht opnieuw uitvoeren die we eerder hadden uitgevoerd, maar hiermee worden alle taken uitgevoerd, zoals het installeren van PostgreSQL, het configureren, het maken van gebruikers en databases. Hiervoor moeten we Ansible beperken om alleen de taken uit te voeren die verband houden met PostgreSQL-configuratie door de optie --tags te gebruiken.

Om de lijst met ondersteunde tags te kennen, kunnen we de opdracht uitvoeren met --list-tags.

$ ansible-playbook -i development.yaml postgres-play.yaml --list-tags
playbook: postgres-play.yaml
  play #1 (postgres_clusters): postgres_clusters        TAGS: []
      TASK TAGS: [always, postgresql, postgresql-configure, postgresql-databases, postgresql-extensions, postgresql-install, postgresql-monit, postgresql-users]

Van de bovenstaande tags zullen we alleen postgresql-configure tag specificeren om de postgresql-instellingen te wijzigen.

$ ansible-playbook  -i development.yaml postgres-play.yaml --tags postgresql-configure

PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...

TASK [anxs.postgresql : PostgreSQL | Update configuration - pt. 2 (postgresql.conf)] ***************************************************************************************************************************
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Reload all conf files] ****************************************************************************************************************************************************
changed: [pg01]

PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=13   changed=2    unreachable=0    failed=0    skipped=6    rescued=0    ignored=0

Zoals u kunt zien in de PLAY RECAP, zijn er slechts 2 wijzigingen doorgevoerd naar het beheerde knooppunt pg01. De eerste is het updaten van de configuratie en de tweede is het herladen van de configuraties.

Controleer of de configuratiewijzigingen van kracht zijn geworden op het beheerde knooppunt.

postgres=# show listen_addresses ;
 listen_addresses
------------------
 localhost
(1 row)

postgres=# show max_connections ;
 max_connections 
-----------------
 100
(1 row)

postgres=# show wal_level ;
 wal_level 
-----------
 minimal
(1 row)

postgres=# show hot_standby ;
 hot_standby 
-------------
 off
(1 row)

postgres=# show statement_timeout;
 statement_timeout 
-------------------
 1min
(1 row)

postgres=# show log_lock_waits ;
 log_lock_waits 
----------------
 on
(1 row)

postgres=# show log_destination ;
 log_destination 
-----------------
 csvlog
(1 row)

postgres=# show log_min_duration_statement;
 log_min_duration_statement 
----------------------------
 
(1 row)

Zoals je kunt zien, zijn sommige configuraties zoals listen_addresses, max_connections, wal_level, hot_standby nog niet van kracht geworden. Deze configuratiewijzigingen vereisen een herstart van PostgreSQL en de rol anxs.postgresql heeft alleen de service zelf opnieuw geladen.

Om een ​​abrupte herstart van PostgreSQL tijdens productie-uren te voorkomen, heeft de oorspronkelijke auteur de herstarttaak mogelijk niet aan de rol toegevoegd. We kunnen de postgresql-service handmatig herstarten tijdens de geplande downtime.

[[email protected] ~]$ sudo systemctl restart postgresql-9.6

[[email protected] ~]$ psql -U postgres
psql (9.6.13)

postgres=# show listen_addresses ;
 listen_addresses 
------------------
 
(1 row)

postgres=# show max_connections ;
 max_connections 
-----------------
 300
(1 row)

postgres=# show wal_level;
 wal_level 
-----------
 replica
(1 row)

postgres=# show hot_standby;
 hot_standby 
-------------
 on
(1 row)

PostgreSQL-gebruikers en -databases maken

We zullen nu de gebruikers "app1" en "app2" en de databases "app1_db" en "app2_db" maken die eigendom zijn van respectievelijk de gebruikers "app1" en "app2".

Ik heb twee nieuwe variabelen toegevoegd, postgresql_users en postgresql_database aan custom.yaml, die de lijst heeft van gebruikers en databases die moeten worden aangemaakt. De rol anxs.postgresql gebruikt de Ansible-module postgresql_users en postgresql_db voor het maken van de gebruiker en de database. U kunt deze documenten raadplegen om de variabelen toe te voegen.

$ cat custom.yaml 
...
...
postgresql_users:
  - name: app1
    pass: md5bb0592c05941d14c231da96950c71b60
    encrypted: yes
  - name: app2
    pass: md5bbb1e4d09b64ca54a237727af46cba7c
    encrypted: yes

postgresql_databases:
  - name: app1_db
    owner: app1 
  - name: app2_db
    owner: app2 

We zullen nu alleen de taken uitvoeren die zijn gekoppeld aan de tags postgresql-users en postgresql-databases.

$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-users,postgresql-databases

PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL users are present] *******************************************************************************************************************************
changed: [pg01] => (item=None)
changed: [pg01] => (item=None)
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL databases are present] ***************************************************************************************************************************
changed: [pg01] => (item={u'owner': u'app1', u'name': u'app1_db'})
changed: [pg01] => (item={u'owner': u'app2', u'name': u'app2_db'})
...
...
PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=6    changed=2    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0

Controleer of de gebruikers en databases zijn gemaakt op de beheerde host.

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 app1      |                                                            | {}
 app2      |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 app1_db   | app1     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 app2_db   | app2     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(5 rows)

Externe hosts toestaan ​​verbinding te maken met de PostgreSQL-server

We staan ​​nu toe dat de externe hosts verbinding maken met de PostgreSQL-service door de variabele postgresql_pg_hba_custom toe te voegen aan custom.yaml

$ cat custom.yaml
...
...
postgresql_pg_hba_custom:
  - {type: "host", database: "all", user: "all", address: "0.0.0.0/0", method: "md5" }

De taken uitvoeren die zijn getagd met postgresql-configure, om de configuratie toe te passen.

$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-configure

Controleren of ik verbinding kan maken met de PostgreSQL-server vanaf mijn controleknooppunt.

$ PGPASSWORD=password psql -h pg01 -U app1 -d app1_db -c 'Select true'
 bool
------
 
(1 row)

Conclusie

Deze blog zou je de basis moeten geven die je moet weten om Ansible te gebruiken voor het implementeren en beheren van PostgreSQL. We hebben echter slechts enkele PostgreSQL-beheertaken behandeld. Afhankelijk van de infrastructuur van uw organisatie, moet u mogelijk een aantal van de standaardconfiguraties overschrijven en nog meer taken toevoegen aan de Ansible-rol.


  1. Maanden tussen twee datums

  2. Versleutel gegevens in SQLite

  3. Navigeren door SQL Server-foutlogboeken

  4. Lijst met databases ophalen van SQL Server