Global transaction IDs (GTID)

Note: �汾����

�� 1.2.0-alpha �汾��ʼ�ͻ��� GTID ����ʹ�ã�������ܲ�����Ҫ��ͬ����Ⱥ��ʹ�ã� ���� MySQL Cluster���������첽��Ⱥ������ MySQL ����ͬ����

�� MySQL 5.6.5-m8 �汾��ʼ��MySQL ʹ�����õ� GTID������Ҫ 1.3.0-alpha �Ժ�汾֧�֡�

PECL/mysqlnd_ms ����ʹ���Լ��� GTID ���棬����ʹ�� MySQL ���õ� GTID������ʹ�����ַ�ʽ�� ����ʹ�÷��񼶱���˵����һ���ġ����ǵ������� concepts section ����˵����

������ʹ�ò���ڲ��� GTID ģ����չʾ���ʹ�÷���˵ĸ�����

����Ϳͻ���ģ��

GTID �� slave ��Ҫͬ���� table �� master �ϻ������ table ��һ����������ÿ�������ύ���������ӡ� ������������������ã���� master �������ϣ����������ݿ����Աȷ��ʹ�����µ� slave �� �ָ��µ� master�����µ� slave �����Ǹ���ֵ��ߵġ�Ӧ�ÿ���ʹ�� GTID ��ѯijһ��д�룬 �Ƿ��Ѿ��� slave ��ͬ����

���������ÿ���ύ�����ʱ������ GTID����Ȼ��� GTID Ҳ������Ӧ���ж�д�����Ƿ�ͬ���� �����Ϳ���ʵ���� session һ���Է��񼶱��У���һ���� master ��ȡ���ݣ�Ҳ���Դ��Ѿ�ͬ�� �� slave �л�ȡ���ݣ��Ӷ����� master �Ķ����ء�

�ͻ��� GTID ģ����һЩ���ƣ����Բο� concepts section ˵����������������ʹ��ǰ����ϸ��ȫ���������Ĺ���ԭ��͸����ر�����֧�֣� ���ڱ��ο��н���˵����

������ master ����һ�������������Ҳ���һ����¼���������������㽨������� ���ݿ����Ա��Ҫ�������������������ڻ��������⣬���ڴ��󱨸���ƣ� ����ܵò����κδ�����Ϣ��

Example #1 �� master ������������

CREATE TABLE `trx` (
  `trx_id` int(11) DEFAULT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO `trx`(`trx_id`) VALUES (1);

�ڲ���������ļ��У���Ҫ�� global_transaction_id_injection �½����趨 on_commit ������һ��Ҫȷ���� UPDATE ��ʹ�õı����ǿɴ�ģ����磺ʹ����һ�������ı� test.trx Ҫ�� trx �����ʡ� ��һ��dz���Ҫ����Ϊ��ͬ�����ݿ����ӣ����ܵ�Ĭ�����ݿ�ѡ�񲢲���ͬ�� ����ȷ�ϣ�ʹ�����ӵ��û�����Ȩ�޶������ִ�� UPDATE ���

�� GTID ����ʱ���򿪴��󱨸档

Example #2 Plugin config: SQL for client-side GTID injection

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "report_error":true
        }
    }
}

Example #3 Transparent global transaction ID injection

<?php
$mysqli 
= new mysqli("myapp""username""password""database");
if (!
$mysqli)
  
/* Of course, your error handling is nicer... */
  
die(sprintf("[%d] %s\n"mysqli_connect_errno(), mysqli_connect_error()));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("DROP TABLE IF EXISTS test"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("CREATE TABLE test(id INT)"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

/* auto commit mode, read on slave, no increment */
if (!($res $mysqli->query("SELECT id FROM test")))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

var_dump($res->fetch_assoc());
?>

�������̻������

array(1) {
  ["id"]=>
  string(1) "1"
}

����ķ������� 3 ������� master �ϣ����Ƕ����� autocommit ��ִ�У����������� 3 �� GTID �����ӡ�ÿ�β��������ִ�������ǰ�����������е� UPDATE �趨 ���� GTID��

��������䣬��Ϊ�� SELECT ��䣬�������� master ��ִ�У� ���Բ������� master ���� GTID��

Note: ���� SQL �� GTID �����Ч�ʵĹ���

�ڿͻ���ͨ�� GTID ģ����ÿ�� SQL ִ�е�ʱ�����Ǻ�û��Ч�ʵ������� ����������Ϊ���ܹ������˵�������������Ϊ��ִ��Ч�ʣ���Ҫ��ʵ�ʵ� ��������������ʹ�á������ڱ������ҵ�����Ч�ʵ�������

Example #4 Plugin config: SQL for fetching GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "fetch_last_gtid" : "SELECT MAX(trx_id) FROM test.trx",
            "report_error":true
        }
    }
}

Example #5 Obtaining GTID after injection

<?php
$mysqli 
= new mysqli("myapp""username""password""database");
if (!
$mysqli)
  
/* Of course, your error handling is nicer... */
  
die(sprintf("[%d] %s\n"mysqli_connect_errno(), mysqli_connect_error()));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("DROP TABLE IF EXISTS test"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

printf("GTID after transaction %s\n"mysqlnd_ms_get_last_gtid($mysqli));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("CREATE TABLE test(id INT)"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

printf("GTID after transaction %s\n"mysqlnd_ms_get_last_gtid($mysqli));
?>

�������̻������

GTID after transaction 7
GTID after transaction 8

Ӧ�ÿ���ͨ�������ȡ���һ��д���������� GTID������mysqlnd_ms_get-last-gtid() ͨ���������ļ��� global_transaction_id_injection �½��� ����� fetch_last-gtid �������������һ�� д���������� GTID������Ӧ���� GTID ���Ӻ���á�

������Ӧ�������Լ�������Щ���ܲ������յ� SQL ��䣬�Ӷ����� GTID�����ң�ʹ�ú��� �������ɵĽ���ѯ GTID Ǩ�Ƶ�����Ӧ���С����磬ʹ���κ� MySQL ���õ� GTID��

����չ����һ�� SQL ����������� GTID ���߱�ʵ��ִ�еõ��� GTID ��������ݡ� �� SELECT �� ��ѯ GTID ֮�䣬�����������Ŀͻ���ִ�� SQL ��䣬�Ӷ������� GTID�����Ի�õ� GTID ���ܱ�ʵ�����ݴ�

Example #6 Plugin config: Checking for a certain GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "fetch_last_gtid" : "SELECT MAX(trx_id) FROM test.trx",
            "check_for_gtid" : "SELECT trx_id FROM test.trx WHERE trx_id >= #GTID",
            "report_error":true
        }
    }
}

Example #7 Session consistency service level and GTID combined

<?php
$mysqli 
= new mysqli("myapp""username""password""database");
if (!
$mysqli)
  
/* Of course, your error handling is nicer... */
  
die(sprintf("[%d] %s\n"mysqli_connect_errno(), mysqli_connect_error()));

/* autocommit ģʽ�£��� master ִ�У��������� GTID */
if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !
$mysqli->query("CREATE TABLE test(id INT)") ||
    !
$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));

/* ��ȡ���һ��д��� GTID */
$gtid mysqlnd_ms_get_last_gtid($mysqli);

/* Session һ���ԣ����Դ� slave ��ȡ������ֻ�� master ��ȡ */
if (false == mysqlnd_ms_set_qos($mysqliMYSQLND_MS_QOS_CONSISTENCY_SESSIONMYSQLND_MS_QOS_OPTION_GTID$gtid)) {
    die(
sprintf("[006] [%d] %s\n"$mysqli->errno$mysqli->error));
}

/* Either run on master or a slave which has replicated the INSERT */
if (!($res $mysqli->query("SELECT id FROM test"))) {
    die(
sprintf("[%d] %s\n"$mysqli->errno$mysqli->error));
}

var_dump($res->fetch_assoc());
?>

ͨ�� mysqlnd_ms_get_last_gtid() ��ȡ�� GTID ���Ա����� Session һ���Է��񼶱�ͨ�� mysqlnd_ms_set_qos() �趨 Session һ���Է��񼶱��������������ȡд������ݡ��ڷ����У� ͨ���ж� INSERT �Ƿ��Ѿ���ͬ���������� SELECT ���ĸ��������ж�ȡ���ݣ�

�����������е����� slave ��������ͨ���鿴 GTID ���е�ֵ���ж��Ƿ� INSERT �Ѿ���ͬ�������ķ����� global_transaction_id_injection �½��У�ʹ�� check_for_gtid �������塣 ��ע�⣬����һ�ֵ�Ч���˷���Դ�ķ����� �� master �Ķ�ȡѹ���ܴ��ʱ��Ӧ�ÿ������ǵIJ������ַ�ʽ�������Ͷ�ȡѹ����

ʹ�÷������˵� GTID

�Դ� MySQL 5.6.5-m8 �汾��ʼ��MySQL ����ͬ����ʼ֧�ַ������˵� GTID��GTID �� �����������ɷ��������ƣ��û����Բ��ٹ�����Щ���⡣��Ҳ����˵������Ҫ������κ� ���ݿ�����ڼ�¼ GTID��Ҳ�������� on_commit �������ͻ���ģ�� �� GTID ������Ҫʹ�á�

�ͻ��˿���˳��ʹ�� GTID ��� Session һ���Է�������ķ�ʽ������������ GTID ģ�� ��һ���ġ���ͬ���� check_for_gtid �� fetch_last_gtid ������Ҫ�������á� ��ע�⣬MySQL 5.6.5-m8 ��һ���з��汾������ִ��ϸ����ʵ�ʵ����а汾������Щ���ܿ����иı䡣

ʹ����������ã��������������۹����κ�һ���ű����ܹ����÷������˵� GTID ���������� ���� mysqlnd_ms_get_last_gtid() �� mysqlnd_ms_set_qos() ����Ҳһ����������ͬ�����ڣ� �������������ü򵥵�˳�����У����Dz���һ��������������ʶ�ź��������ֵ��ַ����� ���ԣ��û������ܼ򵥵�ͨ�� mysqlnd_ms_get_last_gtid() �õ���˳���ж� GTID�� ����ע���� MySQL 5.6.9 �汾��ʼ GTID_DONE �Ѿ��� GTID_EXECUTED �������������� �����У�Ӧ������Ӧ�����

Example #8 ʹ�� MySQL 5.6.5-m8 ���� GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "fetch_last_gtid" : "SELECT @@GLOBAL.GTID_DONE AS trx_id FROM DUAL",
            "check_for_gtid" : "SELECT GTID_SUBSET('#GTID', @@GLOBAL.GTID_DONE) AS trx_id FROM DUAL",
            "report_error":true
        }
    }
}