Spec-Zone.ru › MariaDB

Репликация, когда у первичного и реплицируемого сервера разные определения таблиц

В репликации исторически использовались термины мастер и слейв, но теперь предпочтительнее термины первичный и реплицируемый. Старые термины всё ещё используются в некоторых частях документации и в командах MariaDB, хотя MariaDB 10.5 начала процесс переименования. Процесс документирования продолжается. Следите за прогрессом этой работы на MDEV-18777.

Хотя репликация обычно происходит между первичными и реплицируемыми серверами с одинаковыми определениями таблиц, и это рекомендуется, в некоторых случаях репликация всё ещё может происходить, даже если определения отличаются.

Для успешной репликации таблицам на реплицируемом и первичном серверах не обязательно иметь одинаковое определение. Может быть разное количество столбцов или различные определения данных, и в некоторых случаях репликация всё ещё может быть выполнена.

Разные определения столбцов - продвижение и понижение атрибутов

В некоторых случаях можно реплицировать данные на реплицируемый сервер, у которого столбец имеет другой тип, чем на первичном сервере. Этот процесс называется продвижением атрибута (к большему типу) или понижением атрибута (к меньшему типу).

Условия различаются в зависимости от того, используется ли репликация на основе инструкций или на основе строк.

Репликация на основе инструкций

При использовании репликации на основе инструкций, если инструкция может успешно выполниться на реплицируемом сервере, она будет реплицирована. Если определение столбца на реплицируемом сервере такое же или большего типа, чем на первичном, то репликация может быть успешной. Например, столбец, определённый как VARCHAR(10), успешно будет реплицирован на реплицируемом сервере с определением VARCHAR(12).

Репликация на реплицируемый сервер, где столбец определён как меньшего типа, чем на первичном, также может быть выполнена. Например, при следующих определениях таблиц:

Первичный сервер:

DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | tinyint(4)  | YES  |     | NULL    |       |
| v     | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

Реплицируемый сервер:

DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | tinyint(4)  | YES  |     | NULL    |       |
| v     | varchar(8) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

инструкция

INSERT INTO r VALUES (6,'hi');

будет успешно реплицирована, потому что значение, вставленное в поле v, может быть успешно вставлено как на первичном, так и на реплицируемом сервере с меньшим типом.

Однако следующая инструкция завершится ошибкой:

INSERT INTO r VALUES (7,'abcdefghi')

В этом случае значение подходит для определения на первичном сервере, но слишком велико для поля на реплицируемом сервере, поэтому репликация завершится ошибкой.

SHOW SLAVE STATUS\G
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
...
Last_Errno: 1406
Last_Error: Error 'Data too long for column 'v' at row 1' on query. 
   Default database: 'test'. Query: 'INSERT INTO r VALUES (7,'abcdefghi')'
...

Репликация на основе строк

При использовании репликации на основе строк важно значение переменной slave_type_conversions. По умолчанию значение этой переменной пустое, в этом случае MariaDB не будет выполнять продвижение или понижение атрибутов. Если определения столбцов не совпадают, репликация остановится. Если значение установлено в ALL_NON_LOSSY, безопасная репликация разрешена. Если также установлено в ALL_LOSSY, репликация разрешена, даже если произойдёт потеря данных.

Например:

Первичный сервер:

DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | smallint(6) | YES  |     | NULL    |       |
| v     | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

Реплицируемый сервер:

SHOW VARIABLES LIKE 'slave_ty%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| slave_type_conversions |       |
+------------------------+-------+

 DESC r;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | tinyint(4) | YES  |     | NULL    |       |
| v     | varchar(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

Следующая команда завершится ошибкой:

INSERT INTO r VALUES (3,'c');
SHOW SLAVE STATUS\G;
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
...
Last_Errno: 1677
Last_Error: Column 0 of table 'test.r' cannot be converted from 
  type 'smallint' to type 'tinyint(4)'
...

Изменяя значение slave_type_conversions, можно продолжить репликацию:

SET GLOBAL slave_type_conversions='ALL_NON_LOSSY,ALL_LOSSY';

START SLAVE;
SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Поддерживаемые преобразования

  • Между TINYINT, SMALLINT, MEDIUMINT, INT и BIGINT. Если преобразование с потерей данных поддерживается, значение с первичного сервера будет преобразовано к максимальному или минимальному допустимому значению на реплицируемом сервере. Для преобразований без потери данных, столбец на реплицируемом сервере должен быть достаточно большим. Например, SMALLINT UNSIGNED можно преобразовать в MEDIUMINT, но не SMALLINT SIGNED.

Разное количество или порядок столбцов

Репликация также может произойти, когда у первичного и реплицируемого серверов разное количество столбцов, если выполнены следующие условия:

  • Столбцы должны быть в том же порядке на первичном и реплицируемом серверах
  • Общие столбцы должны быть определены с тем же типом данных
  • Дополнительные столбцы должны быть определены после общих столбцов

Репликация на основе строк

Следующий пример реплицирует с ошибкой (репликация происходит, но данные повреждаются), так как столбцы не в том же порядке.

Первичный сервер:

CREATE OR REPLACE TABLE r (i1 INT, i2 INT);

Реплицируемый сервер:

ALTER TABLE r ADD i3 INT AFTER i1; 

Первичный сервер:

INSERT INTO r (i1,i2) VALUES (1,1);

SELECT * FROM r;
+------+------+
| i1   | i2   |
+------+------+
|    1 |    1 |
+------+------+

Реплицируемый сервер:

SELECT * FROM r;
+------+------+------+
| i1   | i3   | i2   |
+------+------+------+
|    1 |    1 | NULL |
+------+------+------+

Репликация на основе инструкций

Используя репликацию на основе инструкций, тот же пример может работать, даже если столбцы не в том же порядке.

Первичный сервер:

CREATE OR REPLACE TABLE r (i1 INT, i2 INT);

Реплицируемый сервер:

ALTER TABLE r ADD i3 INT AFTER i1; 

Первичный сервер:

INSERT INTO r (i1,i2) VALUES (1,1);

SELECT * FROM r;
+------+------+
| i1   | i2   |
+------+------+
|    1 |    1 |
+------+------+

Реплицируемый сервер:

 SELECT * FROM r;
+------+------+------+
| i1   | i3   | i2   |
+------+------+------+
|    1 | NULL |    1 |
+------+------+------+
Содержание, воспроизведенное на этом сайте, является собственностью соответствующих владельцев, и это содержание не предварительно проверяется MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают мнения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/replication-when-the-primary-and-replica-have-different-table-definitions/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API