PolarDB for MySQL intègre Polar performance schema, une fonctionnalité de surveillance légère permettant de suivre la progression des instructions DDL (Data Definition Language) et l'état des verrous de métadonnées (MDL). Comparé au Performance Schema natif de MySQL, Polar performance schema consomme moins de mémoire et induit une surcharge de performance réduite.
Polar performance schema s'applique uniquement aux tables utilisant le moteur de stockage InnoDB. L'activation du Performance Schema de MySQL désactive automatiquement Polar performance schema.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
-
Un cluster PolarDB for MySQL exécutant l'une des versions de moteur de base de données suivantes :
PolarDB for MySQL 5.7, version de révision 5.7.1.0.35 ou ultérieure
PolarDB for MySQL 8.0.1, version de révision 8.0.1.1.21 ou ultérieure
PolarDB for MySQL 8.0.2, version de révision 8.0.2.2.8 ou ultérieure
-
Un accès au nœud principal. Les instructions DDL ne s'exécutent que sur ce nœud. Selon votre méthode de connexion :
Primary endpoint : interrogez directement l'état des DDL. Consultez Consulter l'endpoint et le numéro de port.
Cluster endpoint : utilisez un hint dans votre instruction SQL pour router la requête vers le nœud principal. Consultez Séparation lecture/écriture.
Pour vérifier la version de votre moteur de base de données, consultez Interroger la version du moteur.
Étape 1 : Activer Polar performance schema
Définissez le paramètre loose_polar_performance_schema sur ON dans la console PolarDB. Ce paramètre prend effet après le redémarrage du cluster. Pour plus d'informations, consultez Configurer les paramètres du cluster et des nœuds.
Le tableau suivant décrit les paramètres de Polar performance schema.
| Paramètre | Description |
|---|---|
loose_polar_performance_schema |
Active ou désactive Polar performance schema. Valeurs valides : ON, OFF. |
loose_polar_performance_schema_enable_row_locks |
Active la collecte des données de surveillance des verrous au niveau ligne. Valeurs valides : OFF (par défaut), ON. Disponible uniquement sur PolarDB for MySQL 8.0.1 et 8.0.2. |
performance_schema_max_thread_instances |
Nombre maximal de threads suivis. Valeurs valides : -1 à 65536. Définissez cette valeur sur -1 pour un ajustement automatique. Ne modifiez ce paramètre que sur instruction explicite. |
performance_schema_max_metadata_locks |
Nombre maximal de MDL surveillés. Valeurs valides : -1 à 1048576. Définissez cette valeur sur -1 pour un ajustement automatique. Ne modifiez ce paramètre que sur instruction explicite. |
Après le redémarrage du cluster, exécutez l'instruction suivante pour confirmer l'activation de la fonctionnalité :
SHOW VARIABLES LIKE 'polar_performance_schema';
Résultat attendu :
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| polar_performance_schema | ON |
+--------------------------+-------+
1 row in set (0.00 sec)
Étape 2 : Consulter la progression de l'exécution des DDL
Interrogez la table performance_schema.events_stages_current pour afficher l'étape actuelle du DDL et sa progression :
SELECT THREAD_ID, EVENT_ID, EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED,
(WORK_COMPLETED/WORK_ESTIMATED)*100 AS PROGRESS
FROM performance_schema.events_stages_current;
Exemple de résultat :
+-----------+----------+------------------------------------------------------+----------------+----------------+----------+
| THREAD_ID | EVENT_ID | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | PROGRESS |
+-----------+----------+------------------------------------------------------+----------------+----------------+----------+
| 3057989 | 13 | stage/innodb/alter table (read PK and internal sort) | 56634 | 330135 | 17.1548 |
+-----------+----------+------------------------------------------------------+----------------+----------------+----------+
1 row in set (0.00 sec)
Pour afficher l'instruction SQL complète associée à l'événement DDL en cours, joignez les tables performance_schema.threads et information_schema.PROCESSLIST :
SELECT esc.THREAD_ID, esc.EVENT_NAME, esc.WORK_COMPLETED, esc.WORK_ESTIMATED, pl.INFO
FROM performance_schema.events_stages_current esc
LEFT JOIN performance_schema.threads th ON esc.thread_id = th.thread_id
LEFT JOIN information_schema.PROCESSLIST pl ON th.PROCESSLIST_ID = pl.ID;
Exemple de résultat :
+-----------+------------------------------------------------------+----------------+----------------+-----------------------------------------------------------------------------------------+
| THREAD_ID | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | INFO |
+-----------+------------------------------------------------------+----------------+----------------+-----------------------------------------------------------------------------------------+
| 3057989 | stage/innodb/alter table (read PK and internal sort) | 77034 | 330519 | ALTER TABLE test.test ALGORITHM=INPLACE, ADD testA VARCHAR(20) NOT NULL DEFAULT 'testA' |
+-----------+------------------------------------------------------+----------------+----------------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
Étape 3 : Consulter l'état des MDL
Interrogez performance_schema.metadata_locks pour afficher tous les verrous de métadonnées actifs dans le cluster :
SELECT * FROM performance_schema.metadata_locks;
Exemple de résultat :
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+------------------------+-----------------+----------------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID |
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+------------------------+-----------------+----------------+
| GLOBAL | NULL | NULL | NULL | 139949462878336 | INTENTION_EXCLUSIVE | STATEMENT | GRANTED | sql_base.cc:3103 | 3055785 | 1 |
| TABLE | test | test | NULL | 139931318980224 | SHARED_WRITE | TRANSACTION | GRANTED | sql_parse.cc:6479 | 3055785 | 1 |
| COMMIT | NULL | NULL | NULL | 139931318980480 | INTENTION_EXCLUSIVE | EXPLICIT | GRANTED | handler.cc:1669 | 3055785 | 1 |
| TABLE | performance_schema | metadata_locks | NULL | 139934227366144 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:6479 | 3057612 | 1 |
| GLOBAL | NULL | NULL | NULL | 139934216849664 | INTENTION_EXCLUSIVE | STATEMENT | GRANTED | sql_base.cc:5519 | 3057989 | 13 |
| SCHEMA | test | NULL | NULL | 139934216849408 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | sql_base.cc:5506 | 3057989 | 13 |
| TABLE | test | test | NULL | 139934216848640 | SHARED_UPGRADABLE | TRANSACTION | GRANTED | sql_parse.cc:6479 | 3057989 | 13 |
| BACKUP LOCK | NULL | NULL | NULL | 139934216849280 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | sql_base.cc:5526 | 3057989 | 13 |
| TABLESPACE | NULL | test/test | NULL | 139934216848384 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | lock.cc:815 | 3057989 | 13 |
| TABLE | test | #sql-17d9_2ea89a | NULL | 139934216848896 | EXCLUSIVE | STATEMENT | GRANTED | sql_table.cc:15054 | 3057989 | 13 |
| GLOBAL | NULL | NULL | NULL | 139934216850176 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | dictionary_impl.cc:416 | 3057989 | 13 |
| TABLESPACE | NULL | test/test | NULL | 139934216849920 | EXCLUSIVE | TRANSACTION | GRANTED | dictionary_impl.cc:397 | 3057989 | 13 |
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+------------------------+-----------------+----------------+
12 rows in set (0.00 sec)
Utilisez la valeur OWNER_THREAD_ID pour rechercher les détails du thread :
SELECT * FROM performance_schema.threads
WHERE THREAD_ID = "<OWNER_THREAD_ID from metadata_locks>";
Diagnostiquer et résoudre les blocages de DDL
Des MDL détenus sur le nœud principal ou sur les nœuds en lecture seule peuvent bloquer les opérations DDL. Les sections suivantes traitent des deux scénarios de blocage les plus courants.
Diagnostiquer un DDL bloqué par « Waiting for table metadata lock »
Dans cette situation, SHOW PROCESSLIST affiche le DDL dans l'état Waiting for table metadata lock.
Étape 1 : exécutez SHOW PROCESSLIST sur le nœud principal. L'exemple suivant utilise le hint force_node pour router la requête vers un nœud spécifique :
/*force_node='pi-bp10k7631d6k3****'*/ SHOW PROCESSLIST;
Exemple de résultat (montrant le DDL bloqué) :
+-----------+---------+-----------------------+------+----------------+---------+---------------------------------+-------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----------+---------+-----------------------+------+----------------+---------+---------------------------------+-------------------------------------------------------------+
| 3067041 | zyg_root| 172.17.XX.XX:48594 | test | Query | 22 | Waiting for table metadata lock | alter table t1 add column d varchar(10),algorithm = inplace |
| 3067443 | zyg_root| 172.17.XX.XX:48602 | test | Sleep | 27 | | NULL |
...
+-----------+---------+-----------------------+------+----------------+---------+---------------------------------+-------------------------------------------------------------+
Étape 2 : l'instruction DDL (ID de processus 3067041) est bloquée. Interrogez performance_schema.metadata_locks pour identifier la cause du blocage :
/*force_node='pi-bp10k7631d6k3****'*/ SELECT * FROM performance_schema.metadata_locks;
Exemple de résultat :
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID |
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
| TABLE | performance_schema | metadata_locks | NULL | 139742994307712 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3810041 | 1 |
| TABLE | test | t1 | NULL | 139742992122240 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3810574 | 1 |
| GLOBAL | NULL | NULL | NULL | 139742992172544 | INTENTION_EXCLUSIVE | STATEMENT | GRANTED | sql_base.cc:5637 | 3810086 | 3 |
| SCHEMA | test | NULL | NULL | 139742993150592 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | sql_base.cc:5624 | 3810086 | 3 |
| TABLE | test | t1 | NULL | 139742993150848 | SHARED_UPGRADABLE | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3810086 | 3 |
| BACKUP LOCK | NULL | NULL | NULL | 139742993844096 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | sql_base.cc:5644 | 3810086 | 3 |
| TABLESPACE | NULL | test/t1 | NULL | 139742991805696 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | lock.cc:815 | 3810086 | 3 |
| TABLE | test | #sql-1b34_2ecca1 | NULL | 139742992091136 | EXCLUSIVE | STATEMENT | GRANTED | sql_table.cc:15532 | 3810086 | 3 |
| TABLE | test | t1 | NULL | 140266021234688 | EXCLUSIVE | TRANSACTION | PENDING | mdl.cc:4124 | 3810086 | 3 |
+-------------+--------------------+------------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
9 rows in set (0.00 sec)
Le thread 3810574 détient un verrou SHARED_READ sur test/t1, empêchant ainsi le thread 3810086 d'acquérir le verrou EXCLUSIVE nécessaire.
Étape 3 : interrogez performance_schema.threads pour identifier la session responsable :
/*force_node='pi-bp10k7631d6k3****'*/ SELECT * FROM performance_schema.threads
WHERE THREAD_ID IN (3810086, 3810574)\G
Exemple de résultat :
*************************** 1. row ***************************
THREAD_ID: 3810086
NAME: thread/sql/one_connection
TYPE: FOREGROUND
PROCESSLIST_ID: 3067041
PROCESSLIST_USER: zyg_root
PROCESSLIST_HOST: 172.17.28.253
PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Query
PROCESSLIST_TIME: 41
PROCESSLIST_STATE: Waiting for table metadata lock
PROCESSLIST_INFO: alter table t1 add column d varchar(10),algorithm = inplace
...
*************************** 2. row ***************************
THREAD_ID: 3810574
NAME: thread/sql/one_connection
TYPE: FOREGROUND
PROCESSLIST_ID: 3067443
PROCESSLIST_USER: zyg_root
PROCESSLIST_HOST: 172.17.28.253
PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Sleep
PROCESSLIST_TIME: 46
PROCESSLIST_STATE: NULL
PROCESSLIST_INFO: NULL
...
2 rows in set (0.01 sec)
Le résultat indique que l'opération DDL bloquée s'exécute sur le thread 3810086, tandis qu'une requête lente s'exécute sur le thread 3810574. Ce dernier détient le verrou. Attendez la validation de sa transaction ou terminez-le avec KILL 3067443, puis réexécutez l'instruction ALTER TABLE.
Diagnostiquer un DDL bloqué par « Wait for syncing with replicas »
Dans ce cas, SHOW PROCESSLIST sur le nœud principal affiche le DDL dans l'état Wait for syncing with replicas.
Étape 1 : exécutez SHOW PROCESSLIST sur le nœud principal :
/*force_node='pi-bp10k7631d6k3****'*/ SHOW PROCESSLIST;
Exemple de résultat (montrant le DDL bloqué) :
+-----------+---------+----------------------+------+----------------+---------+--------------------------------+-------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----------+---------+----------------------+------+----------------+---------+--------------------------------+-------------------------------------------------------------+
| 3067041 | zyg_root| 172.17.28.253:48594 | test | Query | 6 | Wait for syncing with replicas | alter table t1 add column d varchar(10),algorithm = inplace |
...
+-----------+---------+----------------------+------+----------------+---------+--------------------------------+-------------------------------------------------------------+
Étape 2 : utilisez un hint pour interroger performance_schema.metadata_locks sur le nœud en lecture seule concerné :
/*force_node='pi-bp186ko4o21wl****'*/ SELECT * FROM performance_schema.metadata_locks;
Exemple de résultat :
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID |
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
| TABLE | test | t1 | NULL | 139394298895872 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3513381 | 1 |
| TABLE | test | t1 | NULL | 139394298602240 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3519277 | 1 |
| TABLE | test | t1 | NULL | 139917548369664 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3519279 | 1 |
| TABLE | test | t1 | NULL | 139394296661888 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3519278 | 1 |
| TABLE | test | t1 | NULL | 139394297595520 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3519276 | 1 |
| SCHEMA | test | NULL | NULL | 139464322084864 | INTENTION_EXCLUSIVE | EXPLICIT | GRANTED | sql_table.cc:17404 | 57 | 1 |
| TABLE | test | t1 | NULL | 139464322084992 | EXCLUSIVE | EXPLICIT | PENDING | sql_table.cc:17410 | 57 | 1 |
| TABLE | performance_schema | metadata_locks | NULL | 139394296038784 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:7688 | 3518506 | 1 |
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+--------------------+-----------------+----------------+
8 rows in set (0.00 sec)
Les threads 3513381, 3519276, 3519277, 3519278 et 3519279 sur le nœud en lecture seule détiennent tous des verrous SHARED_READ sur test/t1. La présence de plusieurs threads s'explique par l'activation de la fonctionnalité de requête parallèle : chaque worker parallèle détient son propre MDL.
Étape 3 : interrogez performance_schema.threads sur le nœud en lecture seule pour identifier la session source :
/*force_node='pi-bp186ko4o21wl****'*/ SELECT * FROM performance_schema.threads
WHERE THREAD_ID IN (3519278, 3513381, 3519279, 3519276, 3519277)\G
Exemple de résultat :
*************************** 1. row ***************************
THREAD_ID: 3513381
NAME: thread/sql/one_connection
TYPE: FOREGROUND
PROCESSLIST_ID: 538961413
PROCESSLIST_USER: zyg_root
PROCESSLIST_HOST: 172.17.28.253
PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Connect
PROCESSLIST_TIME: 103
PROCESSLIST_STATE: User sleep
PROCESSLIST_INFO: select *,sleep(60) from t1
...
*************************** 2. row ***************************
THREAD_ID: 3519276
NAME: thread/sql/parallel_worker
TYPE: FOREGROUND
PROCESSLIST_ID: 1855915
PROCESSLIST_USER: zyg_root
PROCESSLIST_HOST: 172.17.28.253
PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Sleep
PROCESSLIST_TIME: 103
PROCESSLIST_STATE: Sending data
PROCESSLIST_INFO: select *,sleep(60) from t1
PARENT_THREAD_ID: 3513381
...
5 rows in set (0.00 sec)
Le thread 3513381 exécute select *,sleep(60) from t1 sur le nœud en lecture seule, avec quatre workers parallèles générés. Attendez la fin de la requête ou terminez-la avec KILL 538961413, puis réexécutez l'instruction ALTER TABLE.
Nous contacter
Si vous avez des questions concernant les opérations DDL, contactez le support technique.
Étapes suivantes
Contactez-nous si vous avez d'autres questions sur les opérations DDL.