Como parte de uma migração, criei um novo bufferpool - digamos BP8K - tamanho 8K e um tablespace usando esse bp e uma tabela nesse tablespace, que é carregada com dados. No entanto, recebo um:
SQL1218N There are no pages currently available in bufferpool "4097"
durante esse processo. Olhando para db2top
ele, parece que o bufferpool padrão IBMSYSTEMBP8K é usado em vez de BP8K, o que explica o fenômeno.
Eu vi semelhante quando não há memória compartilhada suficiente para iniciar o bufferpool, mas neste caso BP8K aparece em ambos db2top
, e db2pd -d ... -bufferpools
. Também é possível alterar o tamanho do bp que, no caso de memória insuficiente, geralmente resulta em um aviso de que o bufferpool não foi iniciado.
A db2stop; db2start
corrige o problema, mas isso deveria ser realmente necessário? A migração é um script sql que é executado a partir de uma estrutura de atualização, então prefiro não adicionar algum gancho que force todos os aplicativos. Pensamentos?
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 me ajudou a determinar que o bufferpool não foi iniciado afinal:
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".
A maior parte da memória está configurada para AUTOMATIC
incluir o novo BP, então não sei por que não pode iniciá-lo. Há muita memória disponível no servidor, e o db está usando ~ 1,8 Gb (principalmente bufferpool), então não sei por que o Db2 não pode iniciar o novo bufferpool. Tentei adicionar um commit após a criação do bp, tbspace mas isso não ajudou.
A pergunta agora se torna: Por que o Db2 não pode iniciar este BP. De acordo com os documentos :
Se houver memória suficiente disponível, o conjunto de buffers poderá se tornar ativo imediatamente. Por padrão, novos conjuntos de buffers são criados usando a palavra-chave IMMEDIATE e, na maioria das plataformas, o gerenciador de banco de dados pode adquirir mais memória.
Parece haver muita memória disponível no servidor. O banco de dados alocou aproximadamente 1,8 Gb de memória antes de criar novos tablespaces. As instruções para a criação de bp se parecem com:
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 @
Eu parei o script após a criação do bp, tbspace, forcei todos os aplicativos, depois executei o resto e funcionou bem. Não tenho essa impressão dos documentos, mas talvez isso tenha que ser feito.
Atualizei db cfg memory config
de acordo com:
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>
e verifiquei que SEL_TUNING_MEMORY
estava ativo:
db2 get db cfg for <db> show detail | grep SELF
mas continuo com o mesmo problema.
Depois de restaurar o banco de dados (ou seja, todas as configurações de memória), fiz um pequeno teste:
~]$ 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
Então fiz este teste:
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"
então todas as 3 instruções sql foram bem-sucedidas, mas no diaglog eu encontro:
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>
Resumindo, não tenho a menor idéia de como detectar se o bufferpool foi iniciado ou não.
Confirmar cada instrução em test.sh
(e também no meu script original) é bem-sucedido e não há entrada no diaglog. Apesar disso parecer resolver o problema, também adicionei um atraso após a criação de 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 @
Esta é minha máquina de laboratório e não há praticamente nenhuma outra atividade nela.
db2stop
/db2start
não é necessário para tornar utilizável um bufferpool recém-criado, mas na maioria dos casos você deve desativar e reativar o banco de dados para que os tablespaces possam usar o novo bufferpool.Isso porque, mesmo que a
IMMEDIATE
opção seja especificada ou assumida implicitamenteDependendo dos vários parâmetros de configuração de memória em vigor, principalmente
database_memory
, pode não haver memória suficiente reservada pelo gerenciador de banco de dados para alocar imediatamente o novo bufferpool.Também pode haver um problema de tempo, que é evidente no fragmento de log de diagnóstico adicionado à pergunta posteriormente, onde é possível ver que a criação do espaço de tabela ocorre (com um aviso) antes que o bufferpool para ele seja alocado com êxito. Demora algum tempo para que a nova memória compartilhada para o BP seja alocada - o gerenciador de banco de dados faz um "caminhada de memória", visitando todas as páginas para ter certeza de que foi confirmada pelo sistema operacional. A introdução de uma pausa entre
create bufferpool
ecreate tablespace
pode resolver o problema.Você deve manipular a mensagem possível
SQLCODE = 20189
( ) após . A mensagem correspondente tem a seguinte aparência:SQLSTATE = '01657'
CREATE BUFFERPOOL
A mensagem db2diag.log correspondente:
Posso sugerir o seguinte comando para isso, que gera uma exceção sql, se o bufferpool não puder ser alocado no momento da criação.