web-dev-qa-db-fra.com

Nouveau bufferpool ne pas être utilisé

Dans le cadre d'une migration, j'ai créé un nouveau bufferpool - Dites BP8K - Taille 8K, et un espace de table utilisant ce BP, et une table dans cette tablespace, qui est chargée de données. Cependant, je reçois un:

 SQL1218N There are no pages currently available in bufferpool "4097"

pendant ce processus. Regarder db2top Il semble que la bufferpool IBMSystembp8k par défaut est utilisée à la place de BP8K, ce qui explique les phénomènes.

J'ai vu des semblables quand il n'y a pas suffisamment de mémoire partagée pour démarrer la bufferpool, mais dans ce cas, BP8K apparaît dans les deux db2top, et db2pd -d ... -bufferpools. Il est également possible de modifier la taille du BP qui en cas de mémoire insuffisante, entraîne généralement un avertissement que le bufferpool n'est pas démarré.

UNE db2stop; db2start corrige le problème, mais devrait-il vraiment être nécessaire? La migration est un script SQL qui fonctionne à partir d'un cadre de mise à niveau, je préférerais donc ne pas ajouter de crochet qui force toutes les applications. Les pensées?

db2level
DB21085I  This instance or install (instance name, where applicable: 
"db2inst1") uses "64" bits and DB2 code release "SQL11050" with level 
identifier "0601010F".
Informational tokens are "DB2 v11.5.0.0", "s1906101300", "DYN1906101300AMD64", 
and Fix Pack "0".
Product is installed at "/opt/ibm/db2/V11.5".

db2licm -l
Product name:                     "DB2 Enterprise Server Edition"
License type:                     "Restricted"
Expiry date:                      "Permanent"
Product identifier:               "db2ese"
Version information:              "11.5"
Max amount of memory (GB):        "128"
Max number of cores:              "16"

cat /proc/meminfo 
MemTotal:       164759044 kB
MemFree:         4267032 kB
MemAvailable:   131089520 kB

Mark barinstein m'a aidé à déterminer que le bufferpool n'est pas démarré après tout:

ADM6073W  The table space "TBSPC8K" (ID "9") is configured to use 
          buffer pool ID "3", but this buffer pool is not active at this time. 
          In the interim the table space will use buffer pool ID "4097".

La plupart des mémoire sont définies sur AUTOMATIC y compris le nouveau BP, donc je ne sais pas pourquoi il ne peut pas le démarrer. Il y a beaucoup de mémoire disponible sur le serveur et le dB utilise ~ 1,8 Go (principalement bufferpool), je ne sais pas pourquoi DB2 ne peut pas démarrer le nouveau bufferpool. J'ai essayé d'ajouter un commit après BP, TBSpace Creation, mais cela n'a pas aidé.

La question devient maintenant: pourquoi DB2 ne peut pas démarrer ce BP. Selon - les docs :

S'il y a suffisamment de mémoire disponible, le pool tampon peut devenir actif immédiatement. Par défaut, de nouveaux pools de mémoire tampon sont créés à l'aide du mot clé immédiat et sur la plupart des plates-formes, le gestionnaire de base de données est capable d'acquérir plus de mémoire.

Il semble y avoir beaucoup de mémoire disponible sur le serveur. La base de données a approximativement attribué une mémoire de 1,8 Go avant de créer de nouvelles espaces de table. Les déclarations pour la création BP ressemblent à:

CREATE BUFFERPOOL BP8K SIZE AUTOMATIC PAGESIZE 8K @
CREATE BUFFERPOOL BP16K SIZE AUTOMATIC PAGESIZE 16K @
CREATE BUFFERPOOL BP32K SIZE AUTOMATIC PAGESIZE 32K @
CREATE LARGE TABLESPACE TBSPC8K PAGESIZE 8K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL BP8K @
CREATE LARGE TABLESPACE TBSPC16K PAGESIZE 16K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL BP16K @
CREATE LARGE TABLESPACE TBSPC32K PAGESIZE 32K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL BP32K @

J'ai arrêté le script après BP, TBSpace Creation, a forcé toutes les applications, puis couru le reste et cela a fonctionné bien. Je ne comprends pas cette impression des documents, mais cela doit peut-être être fait.

J'ai mis à jour db cfg memory config selon:

db2 update db cfg for <db> using SELF_TUNING_MEM ON
db2 update db cfg for <db> using DATABASE_MEMORY AUTOMATIC
db2 update db cfg for <db> using SORTHEAP AUTOMATIC
db2 update db cfg for <db> using SHEAPTHRES_SHR AUTOMATIC
db2 connect reset
db2 connect to <db>

et vérifié que SEL_TUNING_MEMORY était actif:

db2 get db cfg for <db> show detail | grep SELF

mais je rencontre toujours le même problème.

Après la restauration de la base de données (c'est-à-dire tous les paramètres de mémoire), j'ai fait un petit test:

~]$ cat test.sh 
#!/bin/sh

OPTS=`getopt -o d:u:p: -- "$@"`
eval set -- "$OPTS"

user=""
passwd=""
while true ; do
    case "$1" in
        -d) db="$2"; shift 2;;
        -u) user="$2"; shift 2;;
        -p) passwd="$2"; shift 2;;
        --) shift; break;;
    esac
done

db2 connect to $db user $user using $passwd
if [ $? -ne 0 ]; then
    exit 1
fi

db2diag -A

db2 +c -td@ "BEGIN
  DECLARE EXIT HANDLER FOR SQLWARNING
    SIGNAL SQLSTATE '75001' SET MESSAGE_TEXT = 'The bufferpool BP8K is not allocated';

  EXECUTE IMMEDIATE 'CREATE BUFFERPOOL BP8K SIZE AUTOMATIC PAGESIZE 8K';
END
@"

db2 +c -td@ "BEGIN
  DECLARE EXIT HANDLER FOR SQLWARNING
    SIGNAL SQLSTATE '75001' SET MESSAGE_TEXT = 'The bufferpool BP8K is not allocated';

  EXECUTE IMMEDIATE 'CREATE LARGE TABLESPACE TBSPC8K PAGESIZE 8K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL BP8K';
END
"

db2 +c -td@ "BEGIN
  DECLARE EXIT HANDLER FOR SQLWARNING
    SIGNAL SQLSTATE '75001' SET MESSAGE_TEXT = 'The bufferpool BP8K is not allocated';

  EXECUTE IMMEDIATE 'COMMIT';
END
"

db2diag -A

Ensuite, j'ai couru ce test:

db2diag: Moving "/opt/nya/users/db2inst1/sqllib/db2dump/DIAG0000/db2diag.log"
         to     "/opt/nya/users/db2inst1/sqllib/db2dump/DIAG0000/db2diag.log_2020-03-28-12.20.57"

DB20000I  The SQL command completed successfully.
DB20000I  The SQL command completed successfully.
DB20000I  The SQL command completed successfully.
db2diag: Moving "/opt/nya/users/db2inst1/sqllib/db2dump/DIAG0000/db2diag.log"
         to     "/opt/nya/users/db2inst1/sqllib/db2dump/DIAG0000/db2diag.log_2020-03-28-12.20.57"

donc, toutes les 3 déclarations SQL ont succédé, mais dans Diagglog, je trouve:

2020-03-28-12.20.57.162214+060 I1800E409             LEVEL: Event
PID     : 5301                 TID : 140165787223936 PROC : db2diag
INSTANCE: db2inst1             NODE : 000
HOSTNAME: gollum
FUNCTION: DB2 UDB, RAS/PD component, pdDiagArchiveDiagnosticLog, probe:88
CREATE  : DB2DIAG.LOG ARCHIVE : /opt/nya/users/db2inst1/sqllib/db2dump/DIAG0000/db2diag.log_2020-03-28-12.20.57 : success
IMPACT  : Potential

2020-03-28-12.20.57.228408+060 E2210E868             LEVEL: Warning
PID     : 17468                TID : 140189351536384 PROC : db2sysc 0
INSTANCE: db2inst1             NODE : 000            DB   : STUDERA
APPHDL  : 0-637                APPID: *LOCAL.db2inst1.200328112127
UOWID   : 1                    ACTID: 4
AUTHID  : DB2INST1             HOSTNAME: gollum
EDUID   : 2442                 EDUNAME: db2agent (STUDERA) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbAssignBufferPool, probe:2
MESSAGE : ADM6073W  The table space "TBSPC8K" (ID "9") is configured to use 
          buffer pool ID "3", but this buffer pool is not active at this time. 
          In the interim the table space will use buffer pool ID "4097".  The 
          inactive buffer pool should become available at next database startup 
          provided that the required memory is available.

2020-03-28-12.20.57.272773+060 I3079E557             LEVEL: Info
PID     : 17468                TID : 140189351536384 PROC : db2sysc 0
INSTANCE: db2inst1             NODE : 000            DB   : STUDERA
APPHDL  : 0-637                APPID: *LOCAL.db2inst1.200328112127
UOWID   : 1                    ACTID: 5
AUTHID  : DB2INST1             HOSTNAME: gollum
EDUID   : 2442                 EDUNAME: db2agent (STUDERA) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbCreateBufferPoolAct, probe:98
MESSAGE : Creating bufferpool "BP8K" Size: "1000"  <automatic>

En bout de ligne, je n'ai pas d'indice sur la manière de détecter si le bufferpool est démarré ou non.

Commettre chaque énoncé dans test.sh (et aussi dans mon script d'origine), réussit et il n'y a pas d'entrée dans Diagglog. Malgré cela semble résoudre le problème, j'ai également ajouté un retard après avoir créé des bufferpools:

CREATE BUFFERPOOL BP8K SIZE AUTOMATIC PAGESIZE 8K @

-- delay commit
BEGIN
    DECLARE now TIMESTAMP;
    DECLARE end TIMESTAMP;
    SET now = TIMESTAMP(GENERATE_UNIQUE());
    SET end = now + 5 seconds;
    WHILE (now < end) DO
        SET now = TIMESTAMP(GENERATE_UNIQUE());
    END WHILE;
END @

Ceci est ma machine de laboratoire et il n'y a pas à peu près aucune autre activité à ce sujet.

2
Lennart

db2stop/db2start N'EST PAS NÉCESSAIRE POUR FAIRE UNE PRISE UTILISABLE DE BUFFERPOOL ANTICIFIQUE, mais dans la plupart des cas, vous devez désactiver et réactiver la base de données des espaces de table pour pouvoir utiliser le nouveau bufferpool.

En effet, même si l'option IMMEDIATE est spécifiée ou implicitement supposée

S'il n'y a pas assez d'espace réservé dans la mémoire partagée de la base de données pour allouer le nouveau pool tampon (sqlstate 01657), l'instruction est exécutée comme DEFERRED.

Selon les différents paramètres de configuration de la mémoire en vigueur, en particulier database_memory , il peut y avoir suffisamment de mémoire réservé par le gestionnaire de base de données pour allouer immédiatement le nouveau bufferpool.

Il pourrait également y avoir également un problème de synchronisation, qui est évident à partir du fragment de journal de diagnostic ajouté à la question plus tard, où on peut voir que la création de l'espace de table se produit (avec un avertissement) avant que le bufferpool n'est attribué avec succès. Il faut un certain temps pour la nouvelle mémoire partagée pour que le BP soit attribué - le gestionnaire de base de données effectue une "promenade de mémoire", visitant chaque page pour s'assurer qu'elle est commise par le système d'exploitation. Introduire une pause entre create bufferpool et create tablespace pourrait résoudre le problème.

3
mustaccio

Vous devriez gérer possible SQLCODE = 20189 (SQLSTATE = '01657') Message après CREATE BUFFERPOOL.
[.____] Le message correspondant ressemble au dessous:

db2 "create bufferpool BP8K SIZE XXXXXX"

SQL20189W  The buffer pool operation (CREATE/ALTER) will not take effect until
the next database startup due to insufficient memory.  SQLSTATE=01657

Le message db2diag.log correspondant:

2020-03-27-17.35.31.377000+180 E6844329F842         LEVEL: Warning
PID     : 7260                 TID : 1612           PROC : db2syscs.exe
INSTANCE: DB2                  NODE : 000           DB   : SAMPLE
APPHDL  : 0-146                APPID: *LOCAL.DB2.200317091324
UOWID   : 12                   ACTID: 1
AUTHID  : DB2ADMIN             HOSTNAME: xxx
EDUID   : 1612                 EDUNAME: db2agent (SAMPLE)
FUNCTION: DB2 UDB, buffer pool services, sqlbCreateBufferPool, probe:5655
MESSAGE : ADM6053W  The CREATE BUFFERPOOL statement for buffer pool "BP8K" (ID
          "3") could not be performed immediately because not enough free
          memory existed in the database shared memory.  The bufferpool will be
          created on the next database restart.  Refer to the documentation for
          SQLCODE 20189.

Je peux suggérer la commande suivante pour cela, qui soulève une sqlexception, si le bufferpool ne peut pas être attribué au moment de la création.

--#SET TERMINATOR @
BEGIN
  DECLARE EXIT HANDLER FOR SQLSTATE '01657'
    SIGNAL SQLSTATE '75001' SET MESSAGE_TEXT = 'The bufferpool BP8K is not allocated';

  -- EXECUTE IMMEDIATE 'CREATE BUFFERPOOL BP8K SIZE XXXXXX';
  -- Just for test:
  ---CALL SYSIBMINTERNAL.SQLEML_RAISE_ERROR(20189, NULL, NULL);
END
@
2
Mark Barinstein