SlideShare une entreprise Scribd logo
1  sur  129
MySQL Replication 101
PHPTek Atlanta 2017
https://joind.in/talk/d98bc
About today
MySQL replication is fairly easy to set up and run, but there are many facets you may not be using that could
make your life much easier. With containers, you will see how to setup basic replication, learn how to use
GTIDs, discover multi-source replication, and then see how to use active-active multi-master Group
Replication. You will understand what the various settings really do and what should be in your config files.
Bring a Linux box with Docker installed and follow along.
Rules: Ask questions!! Only bad question is the one never asked
Be interactive
Try to see ‘big picture’, do not get lost in the config files
3
About me
Dave Stokes
@stoker
david.stokes@oracle.com
elephantdolphin.blogger.com
slideshare.net/davidmstokes
MySQL Community Manager, former MySQL Certification Manager
Live in a small Texas town, have pickup truck & hound dog as required by law 4
Why are you here
What do you do?
What do you want to learn?
What are you long term data needs?
5
What is Replication
6
Replication
Replication enables data from one MySQL database server (the
master) to be copied to one or more MySQL database servers
(the slaves). Replication is asynchronous by default; slaves do
not need to be connected permanently to receive updates from
the master. Depending on the configuration, you can replicate all
databases, selected databases, or even selected tables within a
database.
7
Advantages of Replication
Scale-out solutions - spreading the load among multiple slaves to improve performance. In this
environment, all writes and updates must take place on the master server. Reads, however, may take
place on one or more slaves. This model can improve the performance of writes (since the master is
dedicated to updates), while dramatically increasing read speed across an increasing number of slaves.
Data security - because data is replicated to the slave, and the slave can pause the replication process,
it is possible to run backup services on the slave without corrupting the corresponding master data.
Analytics - live data can be created on the master, while the analysis of the information can take place
on the slave without affecting the performance of the master.
Long-distance data distribution - you can use replication to create a local copy of data for a remote
site to use, without permanent access to the master.
8
MySQL 5.7 supports different methods of replication. The traditional method is based on replicating events from the
master's binary log, and requires the log files and positions in them to be synchronized between master and slave. The
newer method based on global transaction identifiers (GTIDs) is transactional and therefore does not require working with
log files or positions within these files, which greatly simplifies many common replication tasks. Replication using GTIDs
guarantees consistency between master and slave as long as all transactions committed on the master have also been
applied on the slave
Replication in MySQL supports different types of synchronization. The original type of synchronization is one-way,
asynchronous replication, in which one server acts as the master, while one or more other servers act as slaves. This is in
contrast to the synchronous replication which is a characteristic of NDB Cluster. In MySQL 5.7, semisynchronous
replication is supported in addition to the built-in asynchronous replication. With semisynchronous replication, a commit
performed on the master blocks before returning to the session that performed the transaction until at least one slave
acknowledges that it has received and logged the events for the transaction.
There are two core types of replication format, Statement Based Replication (SBR), which replicates entire SQL
statements, and Row Based Replication (RBR), which replicates only the changed rows. You can also use a third variety,
Mixed Based Replication (MBR).
9
MySQL NDB Cluster -- Synchronous Replication
in Cluster
10
Example for visual learners
Master server Slave server
11
Example for visual learners
Master server data changed Slave server copies changes from master
12
Example for visual learners
Master server keeps changing Slave server keeps copying changes
13
Replication Overview
14
Replication Overview
15
Backups: Turn
off SQL thread,
run backup,
restart SQL
thread and
server will
catch up!
Software
16
https://github.com/datacharmer/mysql-
replication-samples.git
Big Thanks to Giuseppe Maxia
https://github.com/datacharmer/mysql-replication-samples.git
17
Basic Replication
Cd mysql-replication-samples-master/docker-replication/simple
18
Configuration files
My-master.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-master-error.log
log-bin = mysql-bin
server-id= 100
19
Configuration files
My-master.cnf
[mysqld] MySQL Server looks for this tag for its config←
user = mysql
log_error = /var/lib/mysql/my-master-error.log
log-bin = mysql-bin
server-id= 100
20
Configuration files
My-master.cnf
[mysqld]
user = mysql user to run mysqld; never use root!!!←
log_error = /var/lib/mysql/my-master-error.log
log-bin = mysql-bin
server-id= 100
21
Configuration files
My-master.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-master-error.log errors←
log-bin = mysql-bin
server-id= 100
22
Configuration files
My-master.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-master-error.log
log-bin = mysql-bin binary log used for replication←
server-id= 100
23
Configuration files
My-master.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-master-error.log
log-bin = mysql-bin
server-id = 100 unique # for all servers in replication←
24
Configuration files
my-slave.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-slave-error.log
log-bin = mysql-bin
relay-log = mysql-relay
server-id= 200
25
Configuration files
my-slave.cnf
[mysqld] same as master←
user = mysql same as master←
log_error = /var/lib/mysql/my-slave-error.log
log-bin = mysql-bin same as master←
relay-log = mysql-relay
server-id= 200
26
Configuration files
my-slave.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-slave-error.log for slave’s errors←
log-bin = mysql-bin
relay-log = mysql-relay
server-id= 200
27
Configuration files
my-slave.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-slave-error.log
log-bin = mysql-bin
relay-log = mysql-relay where slave keeps copy of binlog←
server-id= 200
28
Configuration files
my-slave.cnf
[mysqld]
user = mysql
log_error = /var/lib/mysql/my-slave-error.log
log-bin = mysql-bin
relay-log = mysql-relay
server-id = 200 unique ID←
29
mysql-2node-install.sh
docker run --name mysql-master -v $PWD/my-master.cnf:/etc/my.cnf -e
MYSQL_ROOT_
PASSWORD=secret -d mysql
if [ "$?" != "0" ] ; then exit 1; fi
docker run --name mysql-slave -v $PWD/my-slave.cnf:/etc/my.cnf -e
MYSQL_ROOT_PA
SSWORD=secret -d mysql
if [ "$?" != "0" ] ; then exit 1; fi
echo "# Waiting for nodes to be ready - Sleeping 30 seconds"
sleep 30
./set-2node-replication.sh
30
Run ./mysql-2node-install.sh
Demo
31
Containers
docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
c6c28a955166 mysql "docker-entrypoint..." About a minute ago Up
About a minute 3306/tcp mysql-slave
f2be5a0adbd1 mysql "docker-entrypoint..." About a minute ago Up
About a minute 3306/tcp mysql-master
32
Connect and examine
sudo docker exec -it c6c28a955166 bash
Look at
/var/log/mysql/error.log
/var/lib/mysql
Use mysqlbinlog to look at
/var/lib/mysql/mysql-bin.0000? & mysql-relay.0000?
Show processlist;
33
Check data
root@c6c28a955166:/var/lib/mysql# mysql -u root -p test
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 11
Server version: 5.7.15-log MySQL Community Server (GPL)
….
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> select * from t1;
+---+-------+------------+----------+---------------------+
| i | msg | d | t | dt |
+---+-------+------------+----------+---------------------+
| 1 | test1 | 2017-05-15 | 14:38:45 | 2017-05-15 14:38:34 |
+---+-------+------------+----------+---------------------+
1 row in set (0.00 sec)
mysql>
34
Show Status master & slave
Master mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 1033 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
Slave mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
And look at SHOW PROCESSLIST on both!
35
Show slave status
mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.0.2
Master_User: rdocker
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1033
Relay_Log_File: mysql-relay.000002
Relay_Log_Pos: 1246
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
36
Is slave
running??
Continued
Exec_Master_Log_Pos: 1033
Relay_Log_Space: 1449
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 100
Master_UUID: 1be8f814-397c-11e7-88ea-0242ac110002 37
Continued
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
38
set-2node-replication.sh
Explore file
BTW: ./remove-2node.sh
39
Setup Work Or things replication really, really
needs!
40
Now that you know that you know
who it works it is time to expand the
knowledge you know.
Need a dedicated user for replication
mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY
'slavepass';
mysql> GRANT REPLICATION SLAVE ON *.* TO
'repl'@'%.mydomain.com';
41
Guard this info as it can be a vector for attack!!!
Backup data, copy onto slave
mysql> FLUSH TABLES WITH READ LOCK;
mysql > SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 73 | test | manual,mysql |
+------------------+----------+--------------+------------------+
shell> mysqldump --all-databases --master-data > full.db.dump (on master, copy dump to slave)
shell> mysql -h master < full.db.dump (on slave)
mysql> UNLOCK TABLES;
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;
mysql> START SLAVE;
42
MySQLdbcopy from MySQL Utilites
shell> mysqldbcopy 
--source=root:pass@localhost:3310:/test123/mysql.sock 
--destination=root:pass@localhost:3310:/test123/mysql.sock 
util_test:util_test_copy
# Source on localhost: ... connected.
# Destination on localhost: ... connected.
# Copying database util_test renamed as util_test_copy
# Copying TABLE util_test.t1
# Copying table data.
# Copying TABLE util_test.t2
# Copying table data.
# Copying TABLE util_test.t3
# Copying table data.
# Copying TABLE util_test.t4
# Copying table data.
# Copying VIEW util_test.v1
# Copying TRIGGER util_test.trg
# Copying PROCEDURE util_test.p1
# Copying FUNCTION util_test.f1
# Copying EVENT util_test.e1
# Copying GRANTS from util_test
#...done.
43
Also from MySQL Utilitiesshell> mysqldbcompare --server1=root@host1
--server2=root@host2 --difftype=sql db1:dbx
shell> mysqluserclone --source=root@localhost 
--destination=root@localhost 
joe@localhost sam:secret1@localhost
sally:secret2@localhost
# Source on localhost: ... connected.
# Destination on localhost: ... connected.
# Cloning 2 users...
# Cloning joe@localhost to user sam:secret1@localhost
# Cloning joe@localhost to user
sally:secret2@localhost
# ...done. 44
Also from MySQL Utilities
shell> mysqlrplshow --master=root@localhost:3311 --recurse
--discover-slaves-login=root
# master on localhost: ... connected.
# Finding slaves for master: localhost:3311
# Replication Topology Graph
localhost:3311 (MASTER)
|
+--- localhost:3310 - (SLAVE)
|
+--- localhost:3312 - (SLAVE + MASTER)
|
+--- localhost:3313 - (SLAVE)
45
Also from MySQL Utilities
shell> mysqlrplcheck --master=root@host1:3310 --slave=root@host2:3311
# master on host1: ... connected.
# slave on host2: ... connected.
Test Description Status
------------------------------------------------------------------------
Checking for binary logging on master [pass]
Are there binlog exceptions? [pass]
Replication user exists? [pass]
Checking server_id values [pass]
Is slave connected to master? [pass]
Check master information file [pass]
Checking InnoDB compatibility [pass]
Checking storage engines compatibility [pass]
Checking lower_case_table_names settings [pass]
Checking slave delay (seconds behind master) [pass]
# ...done.
46
Also from MySQL Utilities
shell> mysqlrpladmin --master=root@localhost:3333 
--slaves=root@localhost:3332,root@localhost:3334 health
# Getting health for master: localhost:3333.
#
# Replication Topology Health:
+------------+-------+---------+--------+------------+---------+
| host | port | role | state | gtid_mode | health |
+------------+-------+---------+--------+------------+---------+
| localhost | 3333 | MASTER | UP | ON | OK |
| localhost | 3332 | SLAVE | UP | ON | OK |
| localhost | 3334 | SLAVE | UP | ON | OK |
+------------+-------+---------+--------+------------+---------+
# ...done.
47
Also from MySQL Utilities
shell> mysqlrpladmin --master=root@localhost:3331 
--slaves=root@localhost:3332,root@localhost:3333,root@localho
st:3334 
--candidates=root@localhost:3333,root@localhost:3334 elect
# Electing candidate slave from candidate list then slaves
list.
# Best slave found is located on localhost:3332.
# ...done.
48
Also from MySQL Utilities
shell> mysqlrpladmin 
--slaves=root@localhost:3332,root@localhost:3333,root@localhost:3334

--candidates=root@localhost:3333,root@localhost:3334 failover
# Performing failover.
# Candidate slave localhost:3333 will become the new master.
# Preparing candidate for failover.
# Creating replication user if it does not exist.
# Stopping slaves.
# Performing STOP on all slaves.
# Switching slaves to new master.
# Starting slaves.
# Performing START on all slaves.
# Checking slaves for errors.
# Failover complete.
# ...done.
49
Also from MySQL Utilities
shell> mysqlrplsync --master=user:pass@localhost:3310 
--slaves=rpl:pass@localhost:3311,rpl:pass@localhost:3312
#
# GTID differences between Master and Slaves:
# - Slave 'localhost@3311' is 15 transactions behind Master.
# - Slave 'localhost@3312' is 12 transactions behind Master.
#
# Checking data consistency.
#
# Using Master 'localhost@3310' as base server for comparison.
# Checking 'test_rplsync_db' database...
# - Checking 't0' table data...
# [OK] `test_rplsync_db`.`t0` checksum for server 'localhost@3311'.
# [OK] `test_rplsync_db`.`t0` checksum for server 'localhost@3312'.
# - Checking 't1' table data...
# [OK] `test_rplsync_db`.`t1` checksum for server 'localhost@3311'.
# [OK] `test_rplsync_db`.`t1` checksum for server 'localhost@3312'.
# Checking 'test_db' database...
# - Checking 't0' table data...
# [OK] `test_db`.`t0` checksum for server 'localhost@3311'.
# [OK] `test_db`.`t0` checksum for server 'localhost@3312'.
# - Checking 't1' table data...
# [OK] `test_db`.`t1` checksum for server 'localhost@3311'.
# [OK] `test_db`.`t1` checksum for server 'localhost@3312'.
#
#...done.
#
# SUMMARY: No data consistency issue found.
#
50
Also from MySQL Utilities
shell> mysqlreplicate --master=root@localhost:3306 
--slave=root@localhost:3307 --rpl-user=rpl:rpl -vv
--pedantic
# master on localhost: ... connected.
# slave on localhost: ... connected.
# master id = 2
# slave id = 99
# Checking InnoDB statistics for type and version conflicts.
# Checking storage engines...
# Checking for binary logging on master...
# Setting up replication...
# Flushing tables on master with read lock...
# Connecting slave to master...
# CHANGE MASTER TO MASTER_HOST = [...omitted...]
# Starting slave...
# status: Waiting for master to send event
# error: 0:
# Unlocking tables on master...
# ...done. 51
Also from MySQL Utilitiesshell> mysqlfailover --master=root@localhost:3331 --discover-slaves-login=root
--log=log.txt
MySQL Replication Monitor and Failover Utility
Failover Mode = auto Next Interval = Mon Mar 19 15:56:03 2012
Master Information
------------------
Binary Log File Position Binlog_Do_DB Binlog_Ignore_DB
mysql-bin.000001 571
GTID Executed Set
2A67DE00-2DA1-11E2-A711-00764F2BE90F:1-7 [...]
Replication Health Status
+------------+-------+---------+--------+------------+---------+
| host | port | role | state | gtid_mode | health |
+------------+-------+---------+--------+------------+---------+
| localhost | 3331 | MASTER | UP | ON | OK |
| localhost | 3332 | SLAVE | UP | ON | OK |
| localhost | 3333 | SLAVE | UP | ON | OK |
| localhost | 3334 | SLAVE | UP | ON | OK |
+------------+-------+---------+--------+------------+---------+
Q-quit R-refresh H-health G-GTID Lists U-UUIDs L-log entries
52
Not recommended for
production but very fun to
play with!
Also from MySQL Utilities
Failover starting...
# Candidate slave localhost:3332 will become the new master.
# Preparing candidate for failover.
# Creating replication user if it does not exist.
# Stopping slaves.
# Performing STOP on all slaves.
# Switching slaves to new master.
# Starting slaves.
# Performing START on all slaves.
# Checking slaves for errors.
# Failover complete.
# Discovering slaves for master at localhost:3332
Failover console will restart in 5 seconds.
53
A Peek At The Future
https://youtu.be/8coqFGEKOWw
54
Global Transaction Identifiers -- GTID
Easier to
use
No looking for
logfile offsets
Can Be
Automated
Faster to
setup
55
Global Transaction Identifiers
56
With GTIDs, each transaction can be identified and tracked as it is committed on the originating server
and applied by any slaves. This means that it is not necessary when using GTIDs to refer to log files or
positions within those files when starting a new slave or failing over to a new master, which greatly
simplifies these tasks. Because GTID-based replication is completely transaction-based, it is simple to
determine whether masters and slaves are consistent. As long as all transactions committed on a master
are also committed on a slave, consistency between the two is guaranteed. You can use either
statement-based or row-based replication with GTIDs; however, for best results, we recommend that you
use the row-based format.
What do GTIDs look like?
GTID = source_id:transaction_id
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 (transactions 1-5)
57
Big difference
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;
mysql> START SLAVE;
58
mysql> CHANGE MASTER TO
> MASTER_HOST = host,
> MASTER_PORT = port,
> MASTER_USER = user,
> MASTER_PASSWORD = password,
> MASTER_AUTO_POSITION = 1;
Optional Exercise
Change simple replication from log files to
GTIDs
59
Optional Options
60
Log files in tables not tables
61
InnoDB crash safe - set relay_log_info_repository and
master_info_repository to TABLE
Group Replication
62
63
Cd group-replication
./gr.sh
./gr_start.sh
./gr_test.sh
mysql> show master statusG
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 2182
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-8
1 row in set (0.00 sec)
mysql>
64
Simple Replication Option #1
The easiest way to reproduce all identifiers and transactions on a new server is to make the new server
into the slave of a master that has the entire execution history, and enable global transaction identifiers
on both servers.
Once replication is started, the new server copies the entire binary log from the master and thus obtains
all information about all GTIDs.
This method is simple and effective, but requires the slave to read the binary log from the
master; it can sometimes take a comparatively long time for the new slave to catch up with
the master, so this method is not suitable for fast failover or restoring from backup.
65
Simple Replication Option #2
Playing back the entire transaction history can be time-consuming, and represents a major bottleneck
when setting up a new replication slave. To eliminate this requirement, a snapshot of the data set, the
binary logs and the global transaction information the master contains is imported to the slave. The
binary log is played back, after which replication can be started, allowing the slave to become current
with any remaining transactions.
Option 2a: Use the mysql client to import a dump file created with mysqldump. Use the --master-data
option to include binary logging information and --set-gtid-purged to AUTO (the default) or ON, to
include information about executed transactions. You should have --gtid-mode=ON while importing the
dump on the slave.
Stop the slave, copy the contents of the master's data directory to the slave's data directory, then restart
the slave.
66
Simple Replication Option #2
Option 2b: If gtid_mode is not ON, restart the server with GTID mode enabled.
Import the binary log using mysqlbinlog, with the --read-from-remote-server and --read-from-
remote-master options.
Copy the master's binary log files to the slave. You can make copies from the slave using mysqlbinlog
--read-from-remote-server --raw. These can be read into the slave in either of the following ways:
Update the slave's binlog.index file to point to the copied log files. Then execute a CHANGE MASTER
TO statement in the mysql client to point to the first log file, and START SLAVE to read them.
Use mysqlbinlog > file (without the --raw option) to export the binary log files to SQL files that can be
processed by the mysql client.
67
GTID Restrictions
Need to know!
68
GTID Restrictions
Because GTID-based replication is dependent on transactions, some features
otherwise available in MySQL are not supported when using it. This section
provides information about restrictions on and limitations of replication with GTIDs.
No MyISAM, use InnoDB.
69
GTID Restrictions
CREATE TABLE ... SELECT statements. CREATE TABLE ... SELECT is not safe for statement-based
replication. When using row-based replication, this statement is actually logged as two separate events—
one for the creation of the table, and another for the insertion of rows from the source table into the new
table just created. When this statement is executed within a transaction, it is possible in some cases for
these two events to receive the same transaction identifier, which means that the transaction containing
the inserts is skipped by the slave. Therefore, CREATE TABLE ... SELECT is not supported when using
GTID-based replication.
Temporary tables. CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE statements are not
supported inside transactions when using GTIDs (that is, when the server was started with the
--enforce-gtid-consistency option). It is possible to use these statements with GTIDs enabled, but only
outside of any transaction, and only withautocommit=1.
70
When you need to skip GTIDs
shell> mysqlslavetrx --gtid-set=af6b22ee-7b0b-11e4-aa8d-
606720440b68:7-9 
--slaves=user:pass@localhost:3311,user:pass@localhost:3312
WARNING: Using a password on the command line interface can
be insecure.
#
# GTID set to be skipped for each server:
# - localhost@3311: af6b22ee-7b0b-11e4-aa8d-606720440b68:7-
9
# - localhost@3312: af6b22ee-7b0b-11e4-aa8d-606720440b68:7-
9
#
# Injecting empty transactions for 'localhost:3311'...
# Injecting empty transactions for 'localhost:3312'...
#
#...done.
#
71
SBR, RBR, &
MBR
72
What was that about row based replication?
When using statement-based binary logging, the master writes SQL statements to the binary log.
Replication of the master to the slave works by executing the SQL statements on the slave. This is
called statement-based replication (often abbreviated as SBR), which corresponds to the
standard MySQL statement-based binary logging format. Replication capabilities in MySQL version
5.1.4 and earlier used this format exclusively.
When using row-based logging, the master writes events to the binary log that indicate how individual
table rows are changed. Replication of the master to the slave works by copying the events
representing the changes to the table rows to the slave. This is called row-based replication
(often abbreviated as RBR). *
You can also configure MySQL to use a mix of both statement-based and row-based logging,
depending on which is most appropriate for the change to be logged. This is called mixed-format
logging. When using mixed-format logging, a statement-based log is used by default. Depending
on certain statements, and also the storage engine being used, the log is automatically switched to
row-based in particular cases. Replication using the mixed format is often referred to as mixed-
based replication or mixed-format replication.
73
Advantages of statement-based replication
Proven technology.
Less data written to log files. When updates or deletes affect many rows, this
results in much less storage space required for log files. This also means
that taking and restoring from backups can be accomplished more quickly.
Log files contain all statements that made any changes, so they can be used
to audit the database.
74
Disadvantages of statement-based replication
Statements that are unsafe for SBR. Not all statements which modify data (such as INSERT
DELETE, UPDATE, and REPLACE statements) can be replicated using statement-based
replication. Any nondeterministic behavior is difficult to replicate when using statement-based
replication. Examples of such Data Modification Language (DML) statements include the following:
A statement that depends on a UDF or stored program that is nondeterministic, since the
value returned by such a UDF or stored program or depends on factors other than the
parameters supplied to it. (Row-based replication, however, simply replicates the value
returned by the UDF or stored program, so its effect on table rows and data is the same
on both the master and slave.)
DELETE and UPDATE statements that use a LIMIT clause without an ORDER BY are
nondeterministic. Deterministic UDFs must be applied on the slaves.
75
Disadvantages of statement-based replication
Statements using any of the following functions cannot be replicated properly
using statement-based replication:
 LOAD_FILE()
 UUID(), UUID_SHORT()
 USER()
 FOUND_ROWS()
 SYSDATE() (unless both the master and the slave are started with the --sysdate-is-now option)
 GET_LOCK()
 IS_FREE_LOCK()
 IS_USED_LOCK() 76
Disadvantages of statement-based replication
Statements that cannot be replicated correctly using statement-based replication are logged with a
warning like the one shown here:
[Warning] Statement is not safe to log in statement format.
A similar warning is also issued to the client in such cases. The client can display it using
SHOW WARNINGS.
INSERT ... SELECT requires a greater number of row-level locks than with row-based replication.
UPDATE statements that require a table scan (because no index is used in the WHERE clause)
must lock a greater number of rows than with row-based replication.
For InnoDB: An INSERT statement that uses AUTO_INCREMENT blocks other nonconflicting
INSERT statements.
For complex statements, the statement must be evaluated and executed on the slave before the
rows are updated or inserted. With row-based replication, the slave only has to modify the
affected rows, not execute the full statement.
77
Advantages of row-based replication
All changes can be replicated. This is the safest form of replication.
Note
Statements that update the information in the mysql database—such as GRANT, REVOKE and
the manipulation of triggers, stored routines (including stored procedures), and views—are all
replicated to slaves using statement-based replication.
For statements such as CREATE TABLE ... SELECT, a CREATE statement is generated from the
table definition and replicated using statement-based format, while the row insertions are
replicated using row-based format.
Fewer row locks are required on the master, which thus achieves higher concurrency, for the 78
Disadvantages of row-based replication
RBR can generate more data that must be logged. To replicate a DML statement (such as an UPDATE or DELETE
statement), statement-based replication writes only the statement to the binary log. By contrast, row-based
replication writes each changed row to the binary log. If the statement changes many rows, row-based replication
may write significantly more data to the binary log; this is true even for statements that are rolled back. This also
means that making and restoring a backup can require more time. In addition, the binary log is locked for a longer
time to write the data, which may cause concurrency problems. Use binlog_row_image=minimal to reduce the
disadvantage considerably.
Deterministic UDFs that generate large BLOB values take longer to replicate with row-based replication than with
statement-based replication. This is because the BLOBcolumn value is logged, rather than the statement
generating the data.
You cannot see on the slave what statements were received from the master and executed. However, you can see what
data was changed using mysqlbinlog with the options --base64-output=DECODE-ROWS and --verbose.
Alternatively, use the binlog_rows_query_log_events variable, which if enabled adds a Rows_query event with the
statement to mysqlbinlog output when the -vvoption is used.
79
Splits
80
Read / Write Splits
81
Optimal way to scale reads
Easy to setup
Works well, proven model
82
Change the implementation of
your database access to send
all writes to the master, and to
send reads to either the master
or a slave.
83
Mysqlnd replication and load balancing plugin
https://dev.mysql.com/doc/apis-php/en/apis-php-mysqlnd-ms.html
mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini
/* Statements will be run on the master */
if (!$mysqli->query("DROP TABLE IF EXISTS test")) {
printf("[%d] %sn", $mysqli->errno, $mysqli->error);
}
if (!$mysqli->query("CREATE TABLE test(id INT)")) {
printf("[%d] %sn", $mysqli->errno, $mysqli->error);
}
if (!$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
printf("[%d] %sn", $mysqli->errno, $mysqli->error);
}
/* read-only: statement will be run on a slave */
if (!($res = $mysqli->query("SELECT id FROM test"))) {
printf("[%d] %sn", $mysqli->errno, $mysqli->error);
} else {
$row = $res->fetch_assoc();
$res->close();
See
https://www.daveyshafik.com/archives/tag/mysq
From PHPTek 2015 for more details
Split replication
You do not need to replicate EVERYTHING
--replicate-ignore-db=db_name
--replicate-do-db=db_name
--replicate-do-table=db_name.tbl_name
--replicate-ignore-table=db_name.tbl_name
--replicate-rewrite-db=from_name->to_name
--replicate-wild-do-table=db_name.tbl_name
--replicate-wild-ignore-table=db_name.tbl_name
84
85
Configure each replication slave as follows, before executing START SLAVE:
Replication slave 1 should use --replicate-wild-do-table=databaseA.%.
Replication slave 2 should use --replicate-wild-do-table=databaseB.%.
Replication slave 3 should use --replicate-wild-do-table=databaseC.%.
86
Semi Sync
87
Semisynchronous replication
MySQL replication by default is asynchronous. The master writes events to its binary log but does not know whether or when a slave has retrieved
and processed them. With asynchronous replication, if the master crashes, transactions that it has committed might not have been transmitted to
any slave. Consequently, failover from master to slave in this case may result in failover to a server that is missing transactions relative to the
master.
Semisynchronous replication can be used as an alternative to asynchronous replication:
A slave indicates whether it is semisynchronous-capable when it connects to the master.
If semisynchronous replication is enabled on the master side and there is at least one semisynchronous slave, a thread that performs a
transaction commit on the master blocks and waits until at least one semisynchronous slave acknowledges that it has received all
events for the transaction, or until a timeout occurs.
The slave acknowledges receipt of a transaction's events only after the events have been written to its relay log and flushed to
disk.
If a timeout occurs without any slave having acknowledged the transaction, the master reverts to asynchronous replication. When at least
one semisynchronous slave catches up, the master returns to semisynchronous replication.
Semisynchronous replication must be enabled on both the master and slave sides. If semisynchronous replication is disabled on the
master, or enabled on the master but on no slaves, the master uses asynchronous replication.
As of MySQL 5.7.3, the number of slave acknowledgments the master must receive per transaction before proceeding is configurable
Semisynchronous configuration
Two plugins implement semisynchronous capability. There is one plugin for the master side and one for the slave side.
System variables control plugin behavior. Some examples:
rpl_semi_sync_master_enabled
Controls whether semisynchronous replication is enabled on the master. To enable or disable the plugin, set this variable
to 1 or 0, respectively. The default is 0 (off).
rpl_semi_sync_master_timeout
A value in milliseconds that controls how long the master waits on a commit for acknowledgment from a slave before
timing out and reverting to asynchronous replication. The default value is 10000 (10 seconds).
rpl_semi_sync_slave_enabled
Similar to rpl_semi_sync_master_enabled, but controls the slave plugin.
88
Semisynchronous configuration
On the master:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
On each slave:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS | 89
Troubleshooting
90
When things go #%^@!
91
If you have followed the instructions but your replication setup is not working, the first thing to do is check
the error log for messages. Many users have lost time by not doing this soon enough after encountering
problems.
If you cannot tell from the error log what the problem was, try the following techniques:
Verify that the master has binary logging enabled by issuing a SHOW MASTER STATUS statement.
If logging is enabled, Position is nonzero. If binary logging is not enabled, verify that you are
running the master with the --log-bin option.
Verify that the master and slave both were started with the --server-id option and that the ID value is
unique on each server.
Verify that the slave is running. Use SHOW SLAVE STATUS to check whether the
Slave_IO_Running and Slave_SQL_Running values are both Yes. If not, verify the options that
were used when starting the slave server. For example, --skip-slave-start prevents the slave
threads from starting until you issue a START SLAVEstatement.
When things go #%^@!
92
If the slave is running, check whether it established a connection to the master. Use
SHOW PROCESSLIST, find the I/O and SQL threads and check their State column to see what they
display. If the I/O thread state says Connecting to master, check the following:
o Verify the privileges for the user being used for replication on the master.
o Check that the host name of the master is correct and that you are using the correct port to
connect to the master. The port used for replication is the same as used for client network
communication (the default is 3306). For the host name, ensure that the name resolves to the
correct IP address.
o Check that networking has not been disabled on the master or slave. Look for the
skip-networking option in the configuration file. If present, comment it out or remove it.
o If the master has a firewall or IP filtering configuration, ensure that the network port being used
for MySQL is not being filtered.
o Check that you can reach the master by using ping or traceroute/tracert to reach the host.
When things go #%^@!
93
If a statement that succeeded on the master refuses to run on the slave, try the following procedure if it is not
feasible to do a full database resynchronization by deleting the slave's databases and copying a new snapshot
from the master:
1. Determine whether the affected table on the slave is different from the master table. Try to understand
how this happened. Then make the slave's table identical to the master's and run START SLAVE.
2. If the preceding step does not work or does not apply, try to understand whether it would be safe to
make the update manually (if needed) and then ignore the next statement from the master.
3. If you decide that the slave can skip the next statement from the master, issue the following
statements:
4. mysql> SET GLOBAL sql_slave_skip_counter = N;
mysql> START SLAVE;
5. The value of N should be 1 if the next statement from the master does not use AUTO_INCREMENT or
Group Replication
Master Master
94
Group Replication
Group Replication enables you to create fault-tolerant systems with redundancy by replicating the system state throughout a set
of servers. Consequently, even if some of the servers fail, as long it is not all or a majority, the system is still available, and all it
could have degraded performance or scalability, it is still available. Server failures are isolated and independent. They are
tracked by a group membership service which relies on a distributed failure detector that is able to signal when any servers leave
the group, either voluntarily or due to an unexpected halt. There is a distributed recovery procedure to ensure that when servers
join the group they are brought up to date automatically. There is no need for server fail-over, and the multi-master update
everywhere nature ensures that not even updates are blocked in the event of a single server failure. Therefore MySQL Group
Replication guarantees that the database service is continuously available.
It is important to understand that although the database service is available, in the event of a server crash, those clients
connected to it must be redirected, or failed over, to a different server. This is not something Group Replication attempts to
resolve. A connector, load balancer, router, or some form of middleware are more suitable to deal with this issue.
To summarize, MySQL Group Replication provides a highly available, highly elastic, dependable MySQL service.
95
Examples of Use Case Scenarios
The following examples are typical use cases for Group Replication.
Elastic Replication - Environments that require a very fluid replication infrastructure, where the number
of servers has to grow or shrink dynamically and with as few side-effects as possible. For instance,
database services for the cloud.
Highly Available Shards - Sharding is a popular approach to achieve write scale-out. Use MySQL
Group Replication to implement highly available shards, where each shard maps to a replication
group.
Alternative to Master-Slave replication - In certain situations, using a single master server makes it a
single point of contention. Writing to an entire group may prove more scalable under certain
circumstances.
Autonomic Systems - Additionally, you can deploy MySQL Group Replication purely for the automation
that is built into the replication protocol (described already in this and previous chapters).
96
Failure Detection
There is a failure detection mechanism provided that is able to find and report which servers are silent and as such
assumed to be dead. At a high level, the failure detector is a distributed service that provides information about which
servers may be dead (suspicions). Later if the group agrees that the suspicions are probably true, then the group decides
that a given server has indeed failed. This means that the remaining members in the group take a coordinated decision to
exclude a given member.
Suspicions are triggered when servers go mute. When server A does not receive messages from server B during a given
period, a timeout occurs and a suspicion is raised.
If a server gets isolated from the rest of the group, then it suspects that all others have failed. Being unable to secure
agreement with the group (as it cannot secure a quorum), its suspicion does not have consequences. When a server is
isolated from the group in this way, it is unable to execute any local transactions.
97
Group Membership
MySQL Group Replication relies on a group membership service. This is built into the plugin. It defines which servers are online and
participating in the group. The list of online servers is often referred to as a view. Therefore, every server in the group has a consistent view of
which are the members participating actively in the group at a given moment in time.
Servers have to agree not only on transaction commits, but also which is the current view. Therefore, if servers agree that a new server
becomes part of the group, then the group itself is reconfigured to integrate that server in it, triggering a view change. The opposite also
happens, if a server leaves the group, voluntarily or not, then the group dynamically rearranges its configuration and a view change is
triggered.
Note though that when a member leaves voluntarily, it first initiates a dynamic group reconfiguration. This triggers a procedure, where all
members have to agree on the new view without the leaving server. However, if a member leaves involuntarily (for example it has stopped
unexpectedly or the network connection is down) then the failure detection mechanism realizes this fact and a reconfiguration of the group is
proposed, this one without the failed member. As mentioned this requires agreement from the majority of servers in the group. If the group is
not able to reach agreement (for example it partitioned in such a way that there is no majority of servers online), then the system is not be
able to dynamically change the configuration and as such, blocks to prevent a split-brain situation. Ultimately, this means that the
administrator needs to step in and fix this.
98
Fault Tolerance
MySQL Group Replication builds on an implementation of the Paxos distributed
algorithm to provide distributed coordination between servers. As such, it requires
a majority of servers to be active to reach quorum and thus make a decision. This
has direct impact on the number of failures the system can tolerate without
compromising itself and its overall functionality. The number of servers (n) needed
to tolerate f failures is then n = 2 x f + 1.
In practice this means that to tolerate one failure the group must have three
servers in it. As such if one server fails, there are still two servers to form a
majority (two out of three) and allow the system to continue to make decisions
automatically and progress. However, if a second server fails involuntarily, then
the group (with one server left) blocks, because there is no majority to reach a
decision. 99
Architecture
100
Deploying Instances for Group Replication
101
The first step is to deploy three instances of MySQL Server. Group Replication is a built-in MySQL plugin provided with
MySQL Server 5.7.17 and later. For more background information on MySQL plugins, see
Section 5.5, “MySQL Server Plugins”. This procedure assumes that MySQL Server was downloaded and unpacked into the
directory named mysql-5.7. The following procedure uses one physical machine, therefore each MySQL server instance
requires a specific data directory for the instance. Create the data directories in a directory named data and initialize each
one.
mkdir data
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7
--datadir=$PWD/data/s1
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7
--datadir=$PWD/data/s2
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7
--datadir=$PWD/data/s3
Inside data/s1, data/s2, data/s3 is an initialized data directory, containing the mysql system database and related
tables and much more. To learn more about the initialization procedure.
Note: Do not use --initialize-insecure in production!!!
Group Replication Configuration
[mysqld]
# server configuration
datadir=<full_path_to_data>/data/s1
basedir=<full_path_to_bin>/mysql-5.7/
server_id=1
port=24801
socket=<full_path_to_sock_dir>/s1.sock
102
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-
aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address=
"127.0.0.1:24901"
loose-group_replication_group_seeds=
"127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:2490
3"
loose-group_replication_bootstrap_group= off
Still need a user & start replication
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY
'rpl_pass';
Query OK, 0 rows affected (0,00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO
rpl_user@'%';
Query OK, 0 rows affected, 1 warning (0,00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0,00 sec)
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0,00 sec)
mysql> CHANGE MASTER TO MASTER_USER='rpl_user',
MASTER_PASSWORD='rpl_pass' 
FOR CHANNEL
'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0,01
sec)
INSTALL PLUGIN group_replication SONAME
'group_replication.so';
SET GLOBAL
group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL 103
Is it running?!?!?
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE
|
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
| group_replication_applier | ce9be252-2b71-11e6-b8f4-00212844f856 | myhost | 24801 | ONLINE
|
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
1 row in set (0,00 sec)
104
Test server!
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0,00 sec)
mysql> use test
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0,00 sec)
mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0,01 sec)
105
Test server!
mysql> SELECT * FROM t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0,00 sec)
106
Test data, review log!
mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.17-gr080-log, Binlog ver: 4 |
| binlog.000001 | 123 | Previous_gtids | 1 | 150 | |
| binlog.000001 | 150 | Gtid | 1 | 211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1' |
| binlog.000001 | 211 | Query | 1 | 270 | BEGIN |
| binlog.000001 | 270 | View_change | 1 | 369 | view_id=14724817264259180:1 |
| binlog.000001 | 369 | Query | 1 | 434 | COMMIT |
| binlog.000001 | 434 | Gtid | 1 | 495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2' |
| binlog.000001 | 495 | Query | 1 | 585 | CREATE DATABASE test |
| binlog.000001 | 585 | Gtid | 1 | 646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3' |
| binlog.000001 | 646 | Query | 1 | 770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 | 770 | Gtid | 1 | 831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4' |
| binlog.000001 | 831 | Query | 1 | 899 | BEGIN |
| binlog.000001 | 899 | Table_map | 1 | 942 | table_id: 108 (test.t1) |
| binlog.000001 | 942 | Write_rows | 1 | 984 | table_id: 108 flags: STMT_END_F |
| binlog.000001 | 984 | Xid | 1 | 1011 | COMMIT /* xid=38 */ |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
15 rows in set (0,00 sec)
107
Add second server to group!
[mysqld]
# server configuration
datadir=<full_path_to_data>/data/s2
basedir=<full_path_to_bin>/mysql-5.7/
port=24802
socket=<full_path_to_sock_dir>/s2.sock
#
# Replication configuration parameters
#
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
#
# Group Replication configuration
#
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24902"
loose-group_replication_group_seeds=
"127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off
108
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass';
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' 
FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
START GROUP_REPLICATION;
Add second server to group!
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE
|
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 | myhost | 24801 | ONLINE
|
| group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 | myhost | 24802 | ONLINE
|
+---------------------------+--------------------------------------+-------------+-------------
+---------------+
2 rows in set (0,00 sec)
109
Repeat for other servers!
Single Primary Mode
110
Single Primary Mode
111
In this mode the group has a single-primary server that is set to read-write mode. All the other members in the group are
set to read-only mode (i.e., super-read-only ). This happens automatically. The primary is typically the first server to
boostrap the group, all other servers that join automatically learn about the primary server and are set to read only.
When in single-primary mode, some of the checks deployed in multi-primary mode are disabled, because the system enforces that only a
single writer server is in the group at a time. For example, changes to tables that have cascading foreign keys are allowed, whereas in multi-
primary mode are not. Upon primary member failure, an automatic primary election mechanism chooses the next primary member. The next
primary is selected by ordering the remaining servers lexicographically (using their UUID) and picking the first member in the list.
In the event the primary member is removed from the group, then an election is performed and a new primary is chosen from the remaining
servers in the group. This election is performed by looking at the new view, ordering the server UUIDs in lexicographical order and by picking
the first one. Once a new primary is elected, it is automatically set to read-only and the other secondaries remain as secondaries, and as such,
read-only.
It is a good practice to wait for the new primary to apply its replication related relay-log before re-routing the client applications to it.
Multi-Primary mode
112
Multi-Primary Mode
113
In multi-primary mode, there is no notion of a single primary. There is no need to
engage an election procedure since there is no server playing any special role.
All servers are set to read-write mode when joining the group
Partitioning
114
The group needs to achieve consensus whenever a change that needs to be replicated happens. This is the case for regular transactions but
is also required for group membership changes and some internal messaging that keeps the group consistent. Consensus requires a majority
of group members to agree on a given decision. When a majority of group members is lost, the group is unable to progress and blocks
because it cannot secure majority or quorum.
Quorum may be lost when there are multiple involuntary failures, causing a majority of servers to be removed abruptly from the group. For
example in a group of 5 servers, if 3 of them become silent at once, the majority is compromised and thus no quorum can be achieved. In fact,
the remaining two are not able to tell if the other 3 servers have crashed or whether a network partition has isolated these 2 alone and
therefore the group cannot be reconfigured automatically.
On the other hand, if servers exit the group voluntarily, they instruct the group that it should reconfigure itself. In practice, this means that a
server that is leaving tells others that it is going away. This means that other members can reconfigure the group properly, the consistency of
the membership is maintained and the majority is recalculated. For example, in the above scenario of 5 servers where 3 leave at once, if the 3
leaving servers warn the group that they are leaving, one by one, then the membership is able to adjust itself from 5 to 2, and at the same time,
securing quorum while that happens.
Losing majority
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | ONLINE |
| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | ONLINE |
| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
5 rows in set (0,00 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | UNREACHABLE |
| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | UNREACHABLE |
| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | UNREACHABLE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
5 rows in set (0,00 sec)
115
Unblocking
mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";
Query OK, 0 rows affected (7,13 sec)
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | b60907e7-4ab6-11e6-afb7-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
2 rows in set (0,00 sec)
116
InnoDB
Cluster
MySQL InnoDB
cluster is a collection
of products that work
together to provide a
complete High
Availability solution
for MySQL.
117
Why InnoDB Cluster
A group of MySQL servers can be configured to create a cluster using MySQL
Shell. In the default single-primary mode, the cluster of servers has a single read-
write primary. Multiple secondary servers are replicas of the primary. Creating a
cluster with at least three servers ensures a high availability cluster. A client
application is connected to the primary via MySQL Router. If the primary
fails, a secondary is automatically promoted to the role of primary, and MySQL
Router routes requests to the new primary. Advanced users can also configure a
cluster to have multiple-primaries.
118
119
120
MySQL Router
MySQL Router is part of InnoDB cluster, and is lightweight
middleware that provides transparent routing between your
application and back-end MySQL Servers. It can be used for a wide
variety of use cases, such as providing high availability and
scalability by effectively routing database traffic to appropriate back-
end MySQL Servers. The pluggable architecture also enables
developers to extend MySQL Router for custom use cases
The workflow for using MySQL Router is as follows:
1. MySQL Client or Connector connects to MySQL
Router to, for example, port 6446.
2. Router checks for an available MySQL server.
3. Router opens a connection to a suitable MySQL
server.
4. Router forwards packets back and forth, between the
application and the MySQL server
5. Router disconnects the application if the connected
MySQL server fails. The application can then retry
connecting to Router, and Router then chooses a
different and available MySQL server.
ProxySQL
Routers
Failover
Firewall
Application Proxy
Support many topologies
Supports Group Replication
121
Parallel
Replication
Now within table!
122
MTS Multi Threaded Slaves
123
Upto 5.5 Replication was single threaded
5.6 Multi threaded to schema level
5.7 Multi threaded to table level
Future
http://lefred.be/content/mysql-shell-eye-candy-for-a-future-release/
124
Multi-Source Replication
125
Multi-Source Replication
126
MySQL Multi-Source Replication enables a replication slave to
receive transactions from multiple sources simultaneously. Multi-
source replication can be used to backup multiple servers to a
single server, to merge table shards, and consolidate data from
multiple servers to a single server. Multi-source replication does
not implement any conflict detection or resolution when applying
the transactions, and those tasks are left to the application if
required. In a multi-source replication topology, a slave creates a
replication channel for each master that it should receive
transactions from
MSR Status
mysql> SELECT * FROM replication_connection_statusG;
*************************** 1. row ***************************
CHANNEL_NAME: master1
GROUP_NAME:
SOURCE_UUID: 046e41f8-a223-11e4-a975-0811960cc264
THREAD_ID: 24
SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 0
LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00
RECEIVED_TRANSACTION_SET: 046e41f8-a223-11e4-a975-0811960cc264:4-37
LAST_ERROR_NUMBER: 0
LAST_ERROR_MESSAGE:
LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00
*************************** 2. row ***************************
CHANNEL_NAME: master2
GROUP_NAME:
SOURCE_UUID: 7475e474-a223-11e4-a978-0811960cc264
THREAD_ID: 26
SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 0
LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00
RECEIVED_TRANSACTION_SET: 7475e474-a223-11e4-a978-0811960cc264:4-6
LAST_ERROR_NUMBER: 0
LAST_ERROR_MESSAGE:
LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00
2 rows in set (0.00 sec)
127
128
Contact
Dave Stokes
david.stokes@oracle.com
@stoker
129

Contenu connexe

Tendances

ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)YoungHeon (Roy) Kim
 
MySQL async message subscription platform
MySQL async message subscription platformMySQL async message subscription platform
MySQL async message subscription platformLouis liu
 
Replica Sets (NYC NoSQL Meetup)
Replica Sets (NYC NoSQL Meetup)Replica Sets (NYC NoSQL Meetup)
Replica Sets (NYC NoSQL Meetup)MongoDB
 
MongoDB Database Replication
MongoDB Database ReplicationMongoDB Database Replication
MongoDB Database ReplicationMehdi Valikhani
 
plProxy, pgBouncer, pgBalancer
plProxy, pgBouncer, pgBalancerplProxy, pgBouncer, pgBalancer
plProxy, pgBouncer, pgBalancerelliando dias
 
External Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLExternal Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLAntony T Curtis
 
MySQLドライバの改良と軽量O/Rマッパーの紹介
MySQLドライバの改良と軽量O/Rマッパーの紹介MySQLドライバの改良と軽量O/Rマッパーの紹介
MySQLドライバの改良と軽量O/Rマッパーの紹介kwatch
 
MySQL Audit using Percona audit plugin and ELK
MySQL Audit using Percona audit plugin and ELKMySQL Audit using Percona audit plugin and ELK
MySQL Audit using Percona audit plugin and ELKI Goo Lee
 
Perl Stored Procedures for MySQL (2009)
Perl Stored Procedures for MySQL (2009)Perl Stored Procedures for MySQL (2009)
Perl Stored Procedures for MySQL (2009)Antony T Curtis
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDMydbops
 
MongoDb scalability and high availability with Replica-Set
MongoDb scalability and high availability with Replica-SetMongoDb scalability and high availability with Replica-Set
MongoDb scalability and high availability with Replica-SetVivek Parihar
 
MySQL Document Store
MySQL Document StoreMySQL Document Store
MySQL Document StoreI Goo Lee
 
Managing MariaDB Server operations with Percona Toolkit
Managing MariaDB Server operations with Percona ToolkitManaging MariaDB Server operations with Percona Toolkit
Managing MariaDB Server operations with Percona ToolkitSveta Smirnova
 
Using Perl Stored Procedures for MariaDB
Using Perl Stored Procedures for MariaDBUsing Perl Stored Procedures for MariaDB
Using Perl Stored Procedures for MariaDBAntony T Curtis
 
Multiple instances on linux
Multiple instances on linuxMultiple instances on linux
Multiple instances on linuxVasudeva Rao
 
Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Denish Patel
 

Tendances (20)

ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)
 
MySQL async message subscription platform
MySQL async message subscription platformMySQL async message subscription platform
MySQL async message subscription platform
 
Replica Sets (NYC NoSQL Meetup)
Replica Sets (NYC NoSQL Meetup)Replica Sets (NYC NoSQL Meetup)
Replica Sets (NYC NoSQL Meetup)
 
MongoDB Database Replication
MongoDB Database ReplicationMongoDB Database Replication
MongoDB Database Replication
 
plProxy, pgBouncer, pgBalancer
plProxy, pgBouncer, pgBalancerplProxy, pgBouncer, pgBalancer
plProxy, pgBouncer, pgBalancer
 
External Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLExternal Language Stored Procedures for MySQL
External Language Stored Procedures for MySQL
 
MySQLドライバの改良と軽量O/Rマッパーの紹介
MySQLドライバの改良と軽量O/Rマッパーの紹介MySQLドライバの改良と軽量O/Rマッパーの紹介
MySQLドライバの改良と軽量O/Rマッパーの紹介
 
MySQL Audit using Percona audit plugin and ELK
MySQL Audit using Percona audit plugin and ELKMySQL Audit using Percona audit plugin and ELK
MySQL Audit using Percona audit plugin and ELK
 
Perl Stored Procedures for MySQL (2009)
Perl Stored Procedures for MySQL (2009)Perl Stored Procedures for MySQL (2009)
Perl Stored Procedures for MySQL (2009)
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
 
MongoDb scalability and high availability with Replica-Set
MongoDb scalability and high availability with Replica-SetMongoDb scalability and high availability with Replica-Set
MongoDb scalability and high availability with Replica-Set
 
Redis acc
Redis accRedis acc
Redis acc
 
My SQL 101
My SQL 101My SQL 101
My SQL 101
 
MySQL Document Store
MySQL Document StoreMySQL Document Store
MySQL Document Store
 
Managing MariaDB Server operations with Percona Toolkit
Managing MariaDB Server operations with Percona ToolkitManaging MariaDB Server operations with Percona Toolkit
Managing MariaDB Server operations with Percona Toolkit
 
PostgreSQL Replication Tutorial
PostgreSQL Replication TutorialPostgreSQL Replication Tutorial
PostgreSQL Replication Tutorial
 
Using Perl Stored Procedures for MariaDB
Using Perl Stored Procedures for MariaDBUsing Perl Stored Procedures for MariaDB
Using Perl Stored Procedures for MariaDB
 
Mongodb replication
Mongodb replicationMongodb replication
Mongodb replication
 
Multiple instances on linux
Multiple instances on linuxMultiple instances on linux
Multiple instances on linux
 
Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4
 

En vedette

Know the Science behind WorkFlows using Git & GitHhub
Know the Science behind WorkFlows using Git & GitHhubKnow the Science behind WorkFlows using Git & GitHhub
Know the Science behind WorkFlows using Git & GitHhubEdureka!
 
MySQL Replication Evolution -- Confoo Montreal 2017
MySQL Replication Evolution -- Confoo Montreal 2017MySQL Replication Evolution -- Confoo Montreal 2017
MySQL Replication Evolution -- Confoo Montreal 2017Dave Stokes
 
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaid
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaidHow GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaid
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaidMichael Kimathi
 
Become a Successful Web Developer in Web development Field in 2017
Become a Successful Web Developer in Web development Field in 2017Become a Successful Web Developer in Web development Field in 2017
Become a Successful Web Developer in Web development Field in 2017Imran Qasim
 
O'Leary - Using GitHub for Enterprise and Open Source Documentation
O'Leary - Using GitHub for Enterprise and Open Source DocumentationO'Leary - Using GitHub for Enterprise and Open Source Documentation
O'Leary - Using GitHub for Enterprise and Open Source DocumentationLavaCon
 
Introduction to github using Egit
Introduction to github using EgitIntroduction to github using Egit
Introduction to github using Egitmatz_twt
 
Finding Similar Projects in GitHub using Word2Vec and WMD
Finding Similar Projects in GitHub using Word2Vec and WMDFinding Similar Projects in GitHub using Word2Vec and WMD
Finding Similar Projects in GitHub using Word2Vec and WMDMasudur Rahman
 
Using Git and GitHub Effectively at Emerge Interactive
Using Git and GitHub Effectively at Emerge InteractiveUsing Git and GitHub Effectively at Emerge Interactive
Using Git and GitHub Effectively at Emerge InteractiveMatthew McCullough
 
Advanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsAdvanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsDave Stokes
 

En vedette (9)

Know the Science behind WorkFlows using Git & GitHhub
Know the Science behind WorkFlows using Git & GitHhubKnow the Science behind WorkFlows using Git & GitHhub
Know the Science behind WorkFlows using Git & GitHhub
 
MySQL Replication Evolution -- Confoo Montreal 2017
MySQL Replication Evolution -- Confoo Montreal 2017MySQL Replication Evolution -- Confoo Montreal 2017
MySQL Replication Evolution -- Confoo Montreal 2017
 
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaid
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaidHow GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaid
How GitHub Builds Software at Ruby Conference Kenya 2017 by Mike McQuaid
 
Become a Successful Web Developer in Web development Field in 2017
Become a Successful Web Developer in Web development Field in 2017Become a Successful Web Developer in Web development Field in 2017
Become a Successful Web Developer in Web development Field in 2017
 
O'Leary - Using GitHub for Enterprise and Open Source Documentation
O'Leary - Using GitHub for Enterprise and Open Source DocumentationO'Leary - Using GitHub for Enterprise and Open Source Documentation
O'Leary - Using GitHub for Enterprise and Open Source Documentation
 
Introduction to github using Egit
Introduction to github using EgitIntroduction to github using Egit
Introduction to github using Egit
 
Finding Similar Projects in GitHub using Word2Vec and WMD
Finding Similar Projects in GitHub using Word2Vec and WMDFinding Similar Projects in GitHub using Word2Vec and WMD
Finding Similar Projects in GitHub using Word2Vec and WMD
 
Using Git and GitHub Effectively at Emerge Interactive
Using Git and GitHub Effectively at Emerge InteractiveUsing Git and GitHub Effectively at Emerge Interactive
Using Git and GitHub Effectively at Emerge Interactive
 
Advanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsAdvanced MySQL Query Optimizations
Advanced MySQL Query Optimizations
 

Similaire à MySQL 101 PHPTek 2017

MySQL database replication
MySQL database replicationMySQL database replication
MySQL database replicationPoguttuezhiniVP
 
MySQL Replication Basics -Ohio Linux Fest 2016
MySQL Replication Basics -Ohio Linux Fest 2016MySQL Replication Basics -Ohio Linux Fest 2016
MySQL Replication Basics -Ohio Linux Fest 2016Dave Stokes
 
MySQL Replication Update -- Zendcon 2016
MySQL Replication Update -- Zendcon 2016MySQL Replication Update -- Zendcon 2016
MySQL Replication Update -- Zendcon 2016Dave Stokes
 
ConFoo MySQL Replication Evolution : From Simple to Group Replication
ConFoo  MySQL Replication Evolution : From Simple to Group ReplicationConFoo  MySQL Replication Evolution : From Simple to Group Replication
ConFoo MySQL Replication Evolution : From Simple to Group ReplicationDave Stokes
 
MySQL Replication Overview -- PHPTek 2016
MySQL Replication Overview -- PHPTek 2016MySQL Replication Overview -- PHPTek 2016
MySQL Replication Overview -- PHPTek 2016Dave Stokes
 
Mysql Replication Excerpt 5.1 En
Mysql Replication Excerpt 5.1 EnMysql Replication Excerpt 5.1 En
Mysql Replication Excerpt 5.1 Enliufabin 66688
 
Architecting cloud
Architecting cloudArchitecting cloud
Architecting cloudTahsin Hasan
 
Mater,slave on mysql
Mater,slave on mysqlMater,slave on mysql
Mater,slave on mysqlVasudeva Rao
 
MySQL Utilities -- PyTexas 2015
MySQL Utilities -- PyTexas 2015MySQL Utilities -- PyTexas 2015
MySQL Utilities -- PyTexas 2015Dave Stokes
 
MySQL HA with PaceMaker
MySQL HA with  PaceMakerMySQL HA with  PaceMaker
MySQL HA with PaceMakerKris Buytaert
 
Mysql replication @ gnugroup
Mysql replication @ gnugroupMysql replication @ gnugroup
Mysql replication @ gnugroupJayant Chutke
 
The Proper Care and Feeding of MySQL Databases
The Proper Care and Feeding of MySQL DatabasesThe Proper Care and Feeding of MySQL Databases
The Proper Care and Feeding of MySQL DatabasesDave Stokes
 
My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)Gustavo Rene Antunez
 
Getting started with my sql
Getting started with my sqlGetting started with my sql
Getting started with my sqlWeb Sky
 

Similaire à MySQL 101 PHPTek 2017 (20)

MySQL database replication
MySQL database replicationMySQL database replication
MySQL database replication
 
MySQL Replication Basics -Ohio Linux Fest 2016
MySQL Replication Basics -Ohio Linux Fest 2016MySQL Replication Basics -Ohio Linux Fest 2016
MySQL Replication Basics -Ohio Linux Fest 2016
 
MySQL Replication Update -- Zendcon 2016
MySQL Replication Update -- Zendcon 2016MySQL Replication Update -- Zendcon 2016
MySQL Replication Update -- Zendcon 2016
 
ConFoo MySQL Replication Evolution : From Simple to Group Replication
ConFoo  MySQL Replication Evolution : From Simple to Group ReplicationConFoo  MySQL Replication Evolution : From Simple to Group Replication
ConFoo MySQL Replication Evolution : From Simple to Group Replication
 
MySQL Replication Overview -- PHPTek 2016
MySQL Replication Overview -- PHPTek 2016MySQL Replication Overview -- PHPTek 2016
MySQL Replication Overview -- PHPTek 2016
 
Mysql-Basics.pptx
Mysql-Basics.pptxMysql-Basics.pptx
Mysql-Basics.pptx
 
Mysql Replication Excerpt 5.1 En
Mysql Replication Excerpt 5.1 EnMysql Replication Excerpt 5.1 En
Mysql Replication Excerpt 5.1 En
 
Architecting cloud
Architecting cloudArchitecting cloud
Architecting cloud
 
Mysql
MysqlMysql
Mysql
 
Mater,slave on mysql
Mater,slave on mysqlMater,slave on mysql
Mater,slave on mysql
 
Mysql ppt
Mysql pptMysql ppt
Mysql ppt
 
MySQL Utilities -- PyTexas 2015
MySQL Utilities -- PyTexas 2015MySQL Utilities -- PyTexas 2015
MySQL Utilities -- PyTexas 2015
 
MySQL HA with PaceMaker
MySQL HA with  PaceMakerMySQL HA with  PaceMaker
MySQL HA with PaceMaker
 
Mysql replication @ gnugroup
Mysql replication @ gnugroupMysql replication @ gnugroup
Mysql replication @ gnugroup
 
Database Replication
Database ReplicationDatabase Replication
Database Replication
 
The Proper Care and Feeding of MySQL Databases
The Proper Care and Feeding of MySQL DatabasesThe Proper Care and Feeding of MySQL Databases
The Proper Care and Feeding of MySQL Databases
 
MySQL highav Availability
MySQL highav AvailabilityMySQL highav Availability
MySQL highav Availability
 
My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)
 
Getting started with my sql
Getting started with my sqlGetting started with my sql
Getting started with my sql
 
8.replication
8.replication8.replication
8.replication
 

Plus de Dave Stokes

Locking Down Your MySQL Database.pptx
Locking Down Your MySQL Database.pptxLocking Down Your MySQL Database.pptx
Locking Down Your MySQL Database.pptxDave Stokes
 
Linuxfest Northwest 2022 - MySQL 8.0 Nre Features
Linuxfest Northwest 2022 - MySQL 8.0 Nre FeaturesLinuxfest Northwest 2022 - MySQL 8.0 Nre Features
Linuxfest Northwest 2022 - MySQL 8.0 Nre FeaturesDave Stokes
 
MySQL Indexes and Histograms - RMOUG Training Days 2022
MySQL Indexes and Histograms - RMOUG Training Days 2022MySQL Indexes and Histograms - RMOUG Training Days 2022
MySQL Indexes and Histograms - RMOUG Training Days 2022Dave Stokes
 
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019Dave Stokes
 
Windowing Functions - Little Rock Tech fest 2019
Windowing Functions - Little Rock Tech fest 2019Windowing Functions - Little Rock Tech fest 2019
Windowing Functions - Little Rock Tech fest 2019Dave Stokes
 
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019Dave Stokes
 
Develop PHP Applications with MySQL X DevAPI
Develop PHP Applications with MySQL X DevAPIDevelop PHP Applications with MySQL X DevAPI
Develop PHP Applications with MySQL X DevAPIDave Stokes
 
MySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
MySQL 8 Tips and Tricks from Symfony USA 2018, San FranciscoMySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
MySQL 8 Tips and Tricks from Symfony USA 2018, San FranciscoDave Stokes
 
MySQL without the SQL -- Cascadia PHP
MySQL without the SQL -- Cascadia PHPMySQL without the SQL -- Cascadia PHP
MySQL without the SQL -- Cascadia PHPDave Stokes
 
MySQL 8 Server Optimization Swanseacon 2018
MySQL 8 Server Optimization Swanseacon 2018MySQL 8 Server Optimization Swanseacon 2018
MySQL 8 Server Optimization Swanseacon 2018Dave Stokes
 
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018MySQL Without The SQL -- Oh My! PHP[Tek] June 2018
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018Dave Stokes
 
Presentation Skills for Open Source Folks
Presentation Skills for Open Source FolksPresentation Skills for Open Source Folks
Presentation Skills for Open Source FolksDave Stokes
 
MySQL Without the SQL -- Oh My! Longhorn PHP Conference
MySQL Without the SQL -- Oh My!  Longhorn PHP ConferenceMySQL Without the SQL -- Oh My!  Longhorn PHP Conference
MySQL Without the SQL -- Oh My! Longhorn PHP ConferenceDave Stokes
 
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)Dave Stokes
 
Making MySQL Agile-ish
Making MySQL Agile-ishMaking MySQL Agile-ish
Making MySQL Agile-ishDave Stokes
 
PHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPPHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPDave Stokes
 
MySQL's JSON Data Type and Document Store
MySQL's JSON Data Type and Document StoreMySQL's JSON Data Type and Document Store
MySQL's JSON Data Type and Document StoreDave Stokes
 
Five Database Mistakes and how to fix them -- Confoo Vancouver
Five Database Mistakes and how to fix them -- Confoo VancouverFive Database Mistakes and how to fix them -- Confoo Vancouver
Five Database Mistakes and how to fix them -- Confoo VancouverDave Stokes
 
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016Dave Stokes
 
Why Your Database Queries Stink -SeaGl.org November 11th, 2016
Why Your Database Queries Stink -SeaGl.org November 11th, 2016Why Your Database Queries Stink -SeaGl.org November 11th, 2016
Why Your Database Queries Stink -SeaGl.org November 11th, 2016Dave Stokes
 

Plus de Dave Stokes (20)

Locking Down Your MySQL Database.pptx
Locking Down Your MySQL Database.pptxLocking Down Your MySQL Database.pptx
Locking Down Your MySQL Database.pptx
 
Linuxfest Northwest 2022 - MySQL 8.0 Nre Features
Linuxfest Northwest 2022 - MySQL 8.0 Nre FeaturesLinuxfest Northwest 2022 - MySQL 8.0 Nre Features
Linuxfest Northwest 2022 - MySQL 8.0 Nre Features
 
MySQL Indexes and Histograms - RMOUG Training Days 2022
MySQL Indexes and Histograms - RMOUG Training Days 2022MySQL Indexes and Histograms - RMOUG Training Days 2022
MySQL Indexes and Histograms - RMOUG Training Days 2022
 
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
 
Windowing Functions - Little Rock Tech fest 2019
Windowing Functions - Little Rock Tech fest 2019Windowing Functions - Little Rock Tech fest 2019
Windowing Functions - Little Rock Tech fest 2019
 
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019
MySQL Baics - Texas Linxufest beginners tutorial May 31st, 2019
 
Develop PHP Applications with MySQL X DevAPI
Develop PHP Applications with MySQL X DevAPIDevelop PHP Applications with MySQL X DevAPI
Develop PHP Applications with MySQL X DevAPI
 
MySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
MySQL 8 Tips and Tricks from Symfony USA 2018, San FranciscoMySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
MySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
 
MySQL without the SQL -- Cascadia PHP
MySQL without the SQL -- Cascadia PHPMySQL without the SQL -- Cascadia PHP
MySQL without the SQL -- Cascadia PHP
 
MySQL 8 Server Optimization Swanseacon 2018
MySQL 8 Server Optimization Swanseacon 2018MySQL 8 Server Optimization Swanseacon 2018
MySQL 8 Server Optimization Swanseacon 2018
 
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018MySQL Without The SQL -- Oh My! PHP[Tek] June 2018
MySQL Without The SQL -- Oh My! PHP[Tek] June 2018
 
Presentation Skills for Open Source Folks
Presentation Skills for Open Source FolksPresentation Skills for Open Source Folks
Presentation Skills for Open Source Folks
 
MySQL Without the SQL -- Oh My! Longhorn PHP Conference
MySQL Without the SQL -- Oh My!  Longhorn PHP ConferenceMySQL Without the SQL -- Oh My!  Longhorn PHP Conference
MySQL Without the SQL -- Oh My! Longhorn PHP Conference
 
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)
MySQL 8 -- A new beginning : Sunshine PHP/PHP UK (updated)
 
Making MySQL Agile-ish
Making MySQL Agile-ishMaking MySQL Agile-ish
Making MySQL Agile-ish
 
PHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPPHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHP
 
MySQL's JSON Data Type and Document Store
MySQL's JSON Data Type and Document StoreMySQL's JSON Data Type and Document Store
MySQL's JSON Data Type and Document Store
 
Five Database Mistakes and how to fix them -- Confoo Vancouver
Five Database Mistakes and how to fix them -- Confoo VancouverFive Database Mistakes and how to fix them -- Confoo Vancouver
Five Database Mistakes and how to fix them -- Confoo Vancouver
 
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016
MySQL Utilities -- Cool Tools For You: PHP World Nov 16 2016
 
Why Your Database Queries Stink -SeaGl.org November 11th, 2016
Why Your Database Queries Stink -SeaGl.org November 11th, 2016Why Your Database Queries Stink -SeaGl.org November 11th, 2016
Why Your Database Queries Stink -SeaGl.org November 11th, 2016
 

Dernier

VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...SUHANI PANDEY
 
Trump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts SweatshirtTrump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts Sweatshirtrahman018755
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...SUHANI PANDEY
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.soniya singh
 
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge GraphsEleniIlkou
 
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersMoving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersDamian Radcliffe
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceDelhi Call girls
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableSeo
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLimonikaupta
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...singhpriety023
 
Al Barsha Night Partner +0567686026 Call Girls Dubai
Al Barsha Night Partner +0567686026 Call Girls  DubaiAl Barsha Night Partner +0567686026 Call Girls  Dubai
Al Barsha Night Partner +0567686026 Call Girls DubaiEscorts Call Girls
 

Dernier (20)

VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
 
Trump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts SweatshirtTrump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts Sweatshirt
 
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
 
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
 
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
 
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Green Park Escort Service Delhi N.C.R.
 
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
 
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
 
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersMoving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
 
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
 
Al Barsha Night Partner +0567686026 Call Girls Dubai
Al Barsha Night Partner +0567686026 Call Girls  DubaiAl Barsha Night Partner +0567686026 Call Girls  Dubai
Al Barsha Night Partner +0567686026 Call Girls Dubai
 
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
 

MySQL 101 PHPTek 2017

  • 1. MySQL Replication 101 PHPTek Atlanta 2017 https://joind.in/talk/d98bc
  • 2.
  • 3. About today MySQL replication is fairly easy to set up and run, but there are many facets you may not be using that could make your life much easier. With containers, you will see how to setup basic replication, learn how to use GTIDs, discover multi-source replication, and then see how to use active-active multi-master Group Replication. You will understand what the various settings really do and what should be in your config files. Bring a Linux box with Docker installed and follow along. Rules: Ask questions!! Only bad question is the one never asked Be interactive Try to see ‘big picture’, do not get lost in the config files 3
  • 4. About me Dave Stokes @stoker david.stokes@oracle.com elephantdolphin.blogger.com slideshare.net/davidmstokes MySQL Community Manager, former MySQL Certification Manager Live in a small Texas town, have pickup truck & hound dog as required by law 4
  • 5. Why are you here What do you do? What do you want to learn? What are you long term data needs? 5
  • 7. Replication Replication enables data from one MySQL database server (the master) to be copied to one or more MySQL database servers (the slaves). Replication is asynchronous by default; slaves do not need to be connected permanently to receive updates from the master. Depending on the configuration, you can replicate all databases, selected databases, or even selected tables within a database. 7
  • 8. Advantages of Replication Scale-out solutions - spreading the load among multiple slaves to improve performance. In this environment, all writes and updates must take place on the master server. Reads, however, may take place on one or more slaves. This model can improve the performance of writes (since the master is dedicated to updates), while dramatically increasing read speed across an increasing number of slaves. Data security - because data is replicated to the slave, and the slave can pause the replication process, it is possible to run backup services on the slave without corrupting the corresponding master data. Analytics - live data can be created on the master, while the analysis of the information can take place on the slave without affecting the performance of the master. Long-distance data distribution - you can use replication to create a local copy of data for a remote site to use, without permanent access to the master. 8
  • 9. MySQL 5.7 supports different methods of replication. The traditional method is based on replicating events from the master's binary log, and requires the log files and positions in them to be synchronized between master and slave. The newer method based on global transaction identifiers (GTIDs) is transactional and therefore does not require working with log files or positions within these files, which greatly simplifies many common replication tasks. Replication using GTIDs guarantees consistency between master and slave as long as all transactions committed on the master have also been applied on the slave Replication in MySQL supports different types of synchronization. The original type of synchronization is one-way, asynchronous replication, in which one server acts as the master, while one or more other servers act as slaves. This is in contrast to the synchronous replication which is a characteristic of NDB Cluster. In MySQL 5.7, semisynchronous replication is supported in addition to the built-in asynchronous replication. With semisynchronous replication, a commit performed on the master blocks before returning to the session that performed the transaction until at least one slave acknowledges that it has received and logged the events for the transaction. There are two core types of replication format, Statement Based Replication (SBR), which replicates entire SQL statements, and Row Based Replication (RBR), which replicates only the changed rows. You can also use a third variety, Mixed Based Replication (MBR). 9
  • 10. MySQL NDB Cluster -- Synchronous Replication in Cluster 10
  • 11. Example for visual learners Master server Slave server 11
  • 12. Example for visual learners Master server data changed Slave server copies changes from master 12
  • 13. Example for visual learners Master server keeps changing Slave server keeps copying changes 13
  • 15. Replication Overview 15 Backups: Turn off SQL thread, run backup, restart SQL thread and server will catch up!
  • 17. Big Thanks to Giuseppe Maxia https://github.com/datacharmer/mysql-replication-samples.git 17
  • 19. Configuration files My-master.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-master-error.log log-bin = mysql-bin server-id= 100 19
  • 20. Configuration files My-master.cnf [mysqld] MySQL Server looks for this tag for its config← user = mysql log_error = /var/lib/mysql/my-master-error.log log-bin = mysql-bin server-id= 100 20
  • 21. Configuration files My-master.cnf [mysqld] user = mysql user to run mysqld; never use root!!!← log_error = /var/lib/mysql/my-master-error.log log-bin = mysql-bin server-id= 100 21
  • 22. Configuration files My-master.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-master-error.log errors← log-bin = mysql-bin server-id= 100 22
  • 23. Configuration files My-master.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-master-error.log log-bin = mysql-bin binary log used for replication← server-id= 100 23
  • 24. Configuration files My-master.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-master-error.log log-bin = mysql-bin server-id = 100 unique # for all servers in replication← 24
  • 25. Configuration files my-slave.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-slave-error.log log-bin = mysql-bin relay-log = mysql-relay server-id= 200 25
  • 26. Configuration files my-slave.cnf [mysqld] same as master← user = mysql same as master← log_error = /var/lib/mysql/my-slave-error.log log-bin = mysql-bin same as master← relay-log = mysql-relay server-id= 200 26
  • 27. Configuration files my-slave.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-slave-error.log for slave’s errors← log-bin = mysql-bin relay-log = mysql-relay server-id= 200 27
  • 28. Configuration files my-slave.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-slave-error.log log-bin = mysql-bin relay-log = mysql-relay where slave keeps copy of binlog← server-id= 200 28
  • 29. Configuration files my-slave.cnf [mysqld] user = mysql log_error = /var/lib/mysql/my-slave-error.log log-bin = mysql-bin relay-log = mysql-relay server-id = 200 unique ID← 29
  • 30. mysql-2node-install.sh docker run --name mysql-master -v $PWD/my-master.cnf:/etc/my.cnf -e MYSQL_ROOT_ PASSWORD=secret -d mysql if [ "$?" != "0" ] ; then exit 1; fi docker run --name mysql-slave -v $PWD/my-slave.cnf:/etc/my.cnf -e MYSQL_ROOT_PA SSWORD=secret -d mysql if [ "$?" != "0" ] ; then exit 1; fi echo "# Waiting for nodes to be ready - Sleeping 30 seconds" sleep 30 ./set-2node-replication.sh 30
  • 32. Containers docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c6c28a955166 mysql "docker-entrypoint..." About a minute ago Up About a minute 3306/tcp mysql-slave f2be5a0adbd1 mysql "docker-entrypoint..." About a minute ago Up About a minute 3306/tcp mysql-master 32
  • 33. Connect and examine sudo docker exec -it c6c28a955166 bash Look at /var/log/mysql/error.log /var/lib/mysql Use mysqlbinlog to look at /var/lib/mysql/mysql-bin.0000? & mysql-relay.0000? Show processlist; 33
  • 34. Check data root@c6c28a955166:/var/lib/mysql# mysql -u root -p test Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 11 Server version: 5.7.15-log MySQL Community Server (GPL) …. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> select * from t1; +---+-------+------------+----------+---------------------+ | i | msg | d | t | dt | +---+-------+------------+----------+---------------------+ | 1 | test1 | 2017-05-15 | 14:38:45 | 2017-05-15 14:38:34 | +---+-------+------------+----------+---------------------+ 1 row in set (0.00 sec) mysql> 34
  • 35. Show Status master & slave Master mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 1033 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) Slave mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) And look at SHOW PROCESSLIST on both! 35
  • 36. Show slave status mysql> show slave statusG *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.17.0.2 Master_User: rdocker Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 1033 Relay_Log_File: mysql-relay.000002 Relay_Log_Pos: 1246 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 36 Is slave running??
  • 37. Continued Exec_Master_Log_Pos: 1033 Relay_Log_Space: 1449 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 100 Master_UUID: 1be8f814-397c-11e7-88ea-0242ac110002 37
  • 38. Continued Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) 38
  • 40. Setup Work Or things replication really, really needs! 40 Now that you know that you know who it works it is time to expand the knowledge you know.
  • 41. Need a dedicated user for replication mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.mydomain.com'; 41 Guard this info as it can be a vector for attack!!!
  • 42. Backup data, copy onto slave mysql> FLUSH TABLES WITH READ LOCK; mysql > SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 73 | test | manual,mysql | +------------------+----------+--------------+------------------+ shell> mysqldump --all-databases --master-data > full.db.dump (on master, copy dump to slave) shell> mysql -h master < full.db.dump (on slave) mysql> UNLOCK TABLES; mysql> CHANGE MASTER TO -> MASTER_HOST='master_host_name', -> MASTER_USER='replication_user_name', -> MASTER_PASSWORD='replication_password', -> MASTER_LOG_FILE='recorded_log_file_name', -> MASTER_LOG_POS=recorded_log_position; mysql> START SLAVE; 42
  • 43. MySQLdbcopy from MySQL Utilites shell> mysqldbcopy --source=root:pass@localhost:3310:/test123/mysql.sock --destination=root:pass@localhost:3310:/test123/mysql.sock util_test:util_test_copy # Source on localhost: ... connected. # Destination on localhost: ... connected. # Copying database util_test renamed as util_test_copy # Copying TABLE util_test.t1 # Copying table data. # Copying TABLE util_test.t2 # Copying table data. # Copying TABLE util_test.t3 # Copying table data. # Copying TABLE util_test.t4 # Copying table data. # Copying VIEW util_test.v1 # Copying TRIGGER util_test.trg # Copying PROCEDURE util_test.p1 # Copying FUNCTION util_test.f1 # Copying EVENT util_test.e1 # Copying GRANTS from util_test #...done. 43
  • 44. Also from MySQL Utilitiesshell> mysqldbcompare --server1=root@host1 --server2=root@host2 --difftype=sql db1:dbx shell> mysqluserclone --source=root@localhost --destination=root@localhost joe@localhost sam:secret1@localhost sally:secret2@localhost # Source on localhost: ... connected. # Destination on localhost: ... connected. # Cloning 2 users... # Cloning joe@localhost to user sam:secret1@localhost # Cloning joe@localhost to user sally:secret2@localhost # ...done. 44
  • 45. Also from MySQL Utilities shell> mysqlrplshow --master=root@localhost:3311 --recurse --discover-slaves-login=root # master on localhost: ... connected. # Finding slaves for master: localhost:3311 # Replication Topology Graph localhost:3311 (MASTER) | +--- localhost:3310 - (SLAVE) | +--- localhost:3312 - (SLAVE + MASTER) | +--- localhost:3313 - (SLAVE) 45
  • 46. Also from MySQL Utilities shell> mysqlrplcheck --master=root@host1:3310 --slave=root@host2:3311 # master on host1: ... connected. # slave on host2: ... connected. Test Description Status ------------------------------------------------------------------------ Checking for binary logging on master [pass] Are there binlog exceptions? [pass] Replication user exists? [pass] Checking server_id values [pass] Is slave connected to master? [pass] Check master information file [pass] Checking InnoDB compatibility [pass] Checking storage engines compatibility [pass] Checking lower_case_table_names settings [pass] Checking slave delay (seconds behind master) [pass] # ...done. 46
  • 47. Also from MySQL Utilities shell> mysqlrpladmin --master=root@localhost:3333 --slaves=root@localhost:3332,root@localhost:3334 health # Getting health for master: localhost:3333. # # Replication Topology Health: +------------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +------------+-------+---------+--------+------------+---------+ | localhost | 3333 | MASTER | UP | ON | OK | | localhost | 3332 | SLAVE | UP | ON | OK | | localhost | 3334 | SLAVE | UP | ON | OK | +------------+-------+---------+--------+------------+---------+ # ...done. 47
  • 48. Also from MySQL Utilities shell> mysqlrpladmin --master=root@localhost:3331 --slaves=root@localhost:3332,root@localhost:3333,root@localho st:3334 --candidates=root@localhost:3333,root@localhost:3334 elect # Electing candidate slave from candidate list then slaves list. # Best slave found is located on localhost:3332. # ...done. 48
  • 49. Also from MySQL Utilities shell> mysqlrpladmin --slaves=root@localhost:3332,root@localhost:3333,root@localhost:3334 --candidates=root@localhost:3333,root@localhost:3334 failover # Performing failover. # Candidate slave localhost:3333 will become the new master. # Preparing candidate for failover. # Creating replication user if it does not exist. # Stopping slaves. # Performing STOP on all slaves. # Switching slaves to new master. # Starting slaves. # Performing START on all slaves. # Checking slaves for errors. # Failover complete. # ...done. 49
  • 50. Also from MySQL Utilities shell> mysqlrplsync --master=user:pass@localhost:3310 --slaves=rpl:pass@localhost:3311,rpl:pass@localhost:3312 # # GTID differences between Master and Slaves: # - Slave 'localhost@3311' is 15 transactions behind Master. # - Slave 'localhost@3312' is 12 transactions behind Master. # # Checking data consistency. # # Using Master 'localhost@3310' as base server for comparison. # Checking 'test_rplsync_db' database... # - Checking 't0' table data... # [OK] `test_rplsync_db`.`t0` checksum for server 'localhost@3311'. # [OK] `test_rplsync_db`.`t0` checksum for server 'localhost@3312'. # - Checking 't1' table data... # [OK] `test_rplsync_db`.`t1` checksum for server 'localhost@3311'. # [OK] `test_rplsync_db`.`t1` checksum for server 'localhost@3312'. # Checking 'test_db' database... # - Checking 't0' table data... # [OK] `test_db`.`t0` checksum for server 'localhost@3311'. # [OK] `test_db`.`t0` checksum for server 'localhost@3312'. # - Checking 't1' table data... # [OK] `test_db`.`t1` checksum for server 'localhost@3311'. # [OK] `test_db`.`t1` checksum for server 'localhost@3312'. # #...done. # # SUMMARY: No data consistency issue found. # 50
  • 51. Also from MySQL Utilities shell> mysqlreplicate --master=root@localhost:3306 --slave=root@localhost:3307 --rpl-user=rpl:rpl -vv --pedantic # master on localhost: ... connected. # slave on localhost: ... connected. # master id = 2 # slave id = 99 # Checking InnoDB statistics for type and version conflicts. # Checking storage engines... # Checking for binary logging on master... # Setting up replication... # Flushing tables on master with read lock... # Connecting slave to master... # CHANGE MASTER TO MASTER_HOST = [...omitted...] # Starting slave... # status: Waiting for master to send event # error: 0: # Unlocking tables on master... # ...done. 51
  • 52. Also from MySQL Utilitiesshell> mysqlfailover --master=root@localhost:3331 --discover-slaves-login=root --log=log.txt MySQL Replication Monitor and Failover Utility Failover Mode = auto Next Interval = Mon Mar 19 15:56:03 2012 Master Information ------------------ Binary Log File Position Binlog_Do_DB Binlog_Ignore_DB mysql-bin.000001 571 GTID Executed Set 2A67DE00-2DA1-11E2-A711-00764F2BE90F:1-7 [...] Replication Health Status +------------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +------------+-------+---------+--------+------------+---------+ | localhost | 3331 | MASTER | UP | ON | OK | | localhost | 3332 | SLAVE | UP | ON | OK | | localhost | 3333 | SLAVE | UP | ON | OK | | localhost | 3334 | SLAVE | UP | ON | OK | +------------+-------+---------+--------+------------+---------+ Q-quit R-refresh H-health G-GTID Lists U-UUIDs L-log entries 52 Not recommended for production but very fun to play with!
  • 53. Also from MySQL Utilities Failover starting... # Candidate slave localhost:3332 will become the new master. # Preparing candidate for failover. # Creating replication user if it does not exist. # Stopping slaves. # Performing STOP on all slaves. # Switching slaves to new master. # Starting slaves. # Performing START on all slaves. # Checking slaves for errors. # Failover complete. # Discovering slaves for master at localhost:3332 Failover console will restart in 5 seconds. 53
  • 54. A Peek At The Future https://youtu.be/8coqFGEKOWw 54
  • 55. Global Transaction Identifiers -- GTID Easier to use No looking for logfile offsets Can Be Automated Faster to setup 55
  • 56. Global Transaction Identifiers 56 With GTIDs, each transaction can be identified and tracked as it is committed on the originating server and applied by any slaves. This means that it is not necessary when using GTIDs to refer to log files or positions within those files when starting a new slave or failing over to a new master, which greatly simplifies these tasks. Because GTID-based replication is completely transaction-based, it is simple to determine whether masters and slaves are consistent. As long as all transactions committed on a master are also committed on a slave, consistency between the two is guaranteed. You can use either statement-based or row-based replication with GTIDs; however, for best results, we recommend that you use the row-based format.
  • 57. What do GTIDs look like? GTID = source_id:transaction_id 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 (transactions 1-5) 57
  • 58. Big difference mysql> CHANGE MASTER TO -> MASTER_HOST='master_host_name', -> MASTER_USER='replication_user_name', -> MASTER_PASSWORD='replication_password', -> MASTER_LOG_FILE='recorded_log_file_name', -> MASTER_LOG_POS=recorded_log_position; mysql> START SLAVE; 58 mysql> CHANGE MASTER TO > MASTER_HOST = host, > MASTER_PORT = port, > MASTER_USER = user, > MASTER_PASSWORD = password, > MASTER_AUTO_POSITION = 1;
  • 59. Optional Exercise Change simple replication from log files to GTIDs 59
  • 61. Log files in tables not tables 61 InnoDB crash safe - set relay_log_info_repository and master_info_repository to TABLE
  • 64. mysql> show master statusG *************************** 1. row *************************** File: mysql-bin.000001 Position: 2182 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-8 1 row in set (0.00 sec) mysql> 64
  • 65. Simple Replication Option #1 The easiest way to reproduce all identifiers and transactions on a new server is to make the new server into the slave of a master that has the entire execution history, and enable global transaction identifiers on both servers. Once replication is started, the new server copies the entire binary log from the master and thus obtains all information about all GTIDs. This method is simple and effective, but requires the slave to read the binary log from the master; it can sometimes take a comparatively long time for the new slave to catch up with the master, so this method is not suitable for fast failover or restoring from backup. 65
  • 66. Simple Replication Option #2 Playing back the entire transaction history can be time-consuming, and represents a major bottleneck when setting up a new replication slave. To eliminate this requirement, a snapshot of the data set, the binary logs and the global transaction information the master contains is imported to the slave. The binary log is played back, after which replication can be started, allowing the slave to become current with any remaining transactions. Option 2a: Use the mysql client to import a dump file created with mysqldump. Use the --master-data option to include binary logging information and --set-gtid-purged to AUTO (the default) or ON, to include information about executed transactions. You should have --gtid-mode=ON while importing the dump on the slave. Stop the slave, copy the contents of the master's data directory to the slave's data directory, then restart the slave. 66
  • 67. Simple Replication Option #2 Option 2b: If gtid_mode is not ON, restart the server with GTID mode enabled. Import the binary log using mysqlbinlog, with the --read-from-remote-server and --read-from- remote-master options. Copy the master's binary log files to the slave. You can make copies from the slave using mysqlbinlog --read-from-remote-server --raw. These can be read into the slave in either of the following ways: Update the slave's binlog.index file to point to the copied log files. Then execute a CHANGE MASTER TO statement in the mysql client to point to the first log file, and START SLAVE to read them. Use mysqlbinlog > file (without the --raw option) to export the binary log files to SQL files that can be processed by the mysql client. 67
  • 69. GTID Restrictions Because GTID-based replication is dependent on transactions, some features otherwise available in MySQL are not supported when using it. This section provides information about restrictions on and limitations of replication with GTIDs. No MyISAM, use InnoDB. 69
  • 70. GTID Restrictions CREATE TABLE ... SELECT statements. CREATE TABLE ... SELECT is not safe for statement-based replication. When using row-based replication, this statement is actually logged as two separate events— one for the creation of the table, and another for the insertion of rows from the source table into the new table just created. When this statement is executed within a transaction, it is possible in some cases for these two events to receive the same transaction identifier, which means that the transaction containing the inserts is skipped by the slave. Therefore, CREATE TABLE ... SELECT is not supported when using GTID-based replication. Temporary tables. CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE statements are not supported inside transactions when using GTIDs (that is, when the server was started with the --enforce-gtid-consistency option). It is possible to use these statements with GTIDs enabled, but only outside of any transaction, and only withautocommit=1. 70
  • 71. When you need to skip GTIDs shell> mysqlslavetrx --gtid-set=af6b22ee-7b0b-11e4-aa8d- 606720440b68:7-9 --slaves=user:pass@localhost:3311,user:pass@localhost:3312 WARNING: Using a password on the command line interface can be insecure. # # GTID set to be skipped for each server: # - localhost@3311: af6b22ee-7b0b-11e4-aa8d-606720440b68:7- 9 # - localhost@3312: af6b22ee-7b0b-11e4-aa8d-606720440b68:7- 9 # # Injecting empty transactions for 'localhost:3311'... # Injecting empty transactions for 'localhost:3312'... # #...done. # 71
  • 73. What was that about row based replication? When using statement-based binary logging, the master writes SQL statements to the binary log. Replication of the master to the slave works by executing the SQL statements on the slave. This is called statement-based replication (often abbreviated as SBR), which corresponds to the standard MySQL statement-based binary logging format. Replication capabilities in MySQL version 5.1.4 and earlier used this format exclusively. When using row-based logging, the master writes events to the binary log that indicate how individual table rows are changed. Replication of the master to the slave works by copying the events representing the changes to the table rows to the slave. This is called row-based replication (often abbreviated as RBR). * You can also configure MySQL to use a mix of both statement-based and row-based logging, depending on which is most appropriate for the change to be logged. This is called mixed-format logging. When using mixed-format logging, a statement-based log is used by default. Depending on certain statements, and also the storage engine being used, the log is automatically switched to row-based in particular cases. Replication using the mixed format is often referred to as mixed- based replication or mixed-format replication. 73
  • 74. Advantages of statement-based replication Proven technology. Less data written to log files. When updates or deletes affect many rows, this results in much less storage space required for log files. This also means that taking and restoring from backups can be accomplished more quickly. Log files contain all statements that made any changes, so they can be used to audit the database. 74
  • 75. Disadvantages of statement-based replication Statements that are unsafe for SBR. Not all statements which modify data (such as INSERT DELETE, UPDATE, and REPLACE statements) can be replicated using statement-based replication. Any nondeterministic behavior is difficult to replicate when using statement-based replication. Examples of such Data Modification Language (DML) statements include the following: A statement that depends on a UDF or stored program that is nondeterministic, since the value returned by such a UDF or stored program or depends on factors other than the parameters supplied to it. (Row-based replication, however, simply replicates the value returned by the UDF or stored program, so its effect on table rows and data is the same on both the master and slave.) DELETE and UPDATE statements that use a LIMIT clause without an ORDER BY are nondeterministic. Deterministic UDFs must be applied on the slaves. 75
  • 76. Disadvantages of statement-based replication Statements using any of the following functions cannot be replicated properly using statement-based replication:  LOAD_FILE()  UUID(), UUID_SHORT()  USER()  FOUND_ROWS()  SYSDATE() (unless both the master and the slave are started with the --sysdate-is-now option)  GET_LOCK()  IS_FREE_LOCK()  IS_USED_LOCK() 76
  • 77. Disadvantages of statement-based replication Statements that cannot be replicated correctly using statement-based replication are logged with a warning like the one shown here: [Warning] Statement is not safe to log in statement format. A similar warning is also issued to the client in such cases. The client can display it using SHOW WARNINGS. INSERT ... SELECT requires a greater number of row-level locks than with row-based replication. UPDATE statements that require a table scan (because no index is used in the WHERE clause) must lock a greater number of rows than with row-based replication. For InnoDB: An INSERT statement that uses AUTO_INCREMENT blocks other nonconflicting INSERT statements. For complex statements, the statement must be evaluated and executed on the slave before the rows are updated or inserted. With row-based replication, the slave only has to modify the affected rows, not execute the full statement. 77
  • 78. Advantages of row-based replication All changes can be replicated. This is the safest form of replication. Note Statements that update the information in the mysql database—such as GRANT, REVOKE and the manipulation of triggers, stored routines (including stored procedures), and views—are all replicated to slaves using statement-based replication. For statements such as CREATE TABLE ... SELECT, a CREATE statement is generated from the table definition and replicated using statement-based format, while the row insertions are replicated using row-based format. Fewer row locks are required on the master, which thus achieves higher concurrency, for the 78
  • 79. Disadvantages of row-based replication RBR can generate more data that must be logged. To replicate a DML statement (such as an UPDATE or DELETE statement), statement-based replication writes only the statement to the binary log. By contrast, row-based replication writes each changed row to the binary log. If the statement changes many rows, row-based replication may write significantly more data to the binary log; this is true even for statements that are rolled back. This also means that making and restoring a backup can require more time. In addition, the binary log is locked for a longer time to write the data, which may cause concurrency problems. Use binlog_row_image=minimal to reduce the disadvantage considerably. Deterministic UDFs that generate large BLOB values take longer to replicate with row-based replication than with statement-based replication. This is because the BLOBcolumn value is logged, rather than the statement generating the data. You cannot see on the slave what statements were received from the master and executed. However, you can see what data was changed using mysqlbinlog with the options --base64-output=DECODE-ROWS and --verbose. Alternatively, use the binlog_rows_query_log_events variable, which if enabled adds a Rows_query event with the statement to mysqlbinlog output when the -vvoption is used. 79
  • 81. Read / Write Splits 81 Optimal way to scale reads Easy to setup Works well, proven model
  • 82. 82 Change the implementation of your database access to send all writes to the master, and to send reads to either the master or a slave.
  • 83. 83 Mysqlnd replication and load balancing plugin https://dev.mysql.com/doc/apis-php/en/apis-php-mysqlnd-ms.html mysqlnd_ms.enable=1 mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini /* Statements will be run on the master */ if (!$mysqli->query("DROP TABLE IF EXISTS test")) { printf("[%d] %sn", $mysqli->errno, $mysqli->error); } if (!$mysqli->query("CREATE TABLE test(id INT)")) { printf("[%d] %sn", $mysqli->errno, $mysqli->error); } if (!$mysqli->query("INSERT INTO test(id) VALUES (1)")) { printf("[%d] %sn", $mysqli->errno, $mysqli->error); } /* read-only: statement will be run on a slave */ if (!($res = $mysqli->query("SELECT id FROM test"))) { printf("[%d] %sn", $mysqli->errno, $mysqli->error); } else { $row = $res->fetch_assoc(); $res->close(); See https://www.daveyshafik.com/archives/tag/mysq From PHPTek 2015 for more details
  • 84. Split replication You do not need to replicate EVERYTHING --replicate-ignore-db=db_name --replicate-do-db=db_name --replicate-do-table=db_name.tbl_name --replicate-ignore-table=db_name.tbl_name --replicate-rewrite-db=from_name->to_name --replicate-wild-do-table=db_name.tbl_name --replicate-wild-ignore-table=db_name.tbl_name 84
  • 85. 85 Configure each replication slave as follows, before executing START SLAVE: Replication slave 1 should use --replicate-wild-do-table=databaseA.%. Replication slave 2 should use --replicate-wild-do-table=databaseB.%. Replication slave 3 should use --replicate-wild-do-table=databaseC.%.
  • 87. 87 Semisynchronous replication MySQL replication by default is asynchronous. The master writes events to its binary log but does not know whether or when a slave has retrieved and processed them. With asynchronous replication, if the master crashes, transactions that it has committed might not have been transmitted to any slave. Consequently, failover from master to slave in this case may result in failover to a server that is missing transactions relative to the master. Semisynchronous replication can be used as an alternative to asynchronous replication: A slave indicates whether it is semisynchronous-capable when it connects to the master. If semisynchronous replication is enabled on the master side and there is at least one semisynchronous slave, a thread that performs a transaction commit on the master blocks and waits until at least one semisynchronous slave acknowledges that it has received all events for the transaction, or until a timeout occurs. The slave acknowledges receipt of a transaction's events only after the events have been written to its relay log and flushed to disk. If a timeout occurs without any slave having acknowledged the transaction, the master reverts to asynchronous replication. When at least one semisynchronous slave catches up, the master returns to semisynchronous replication. Semisynchronous replication must be enabled on both the master and slave sides. If semisynchronous replication is disabled on the master, or enabled on the master but on no slaves, the master uses asynchronous replication. As of MySQL 5.7.3, the number of slave acknowledgments the master must receive per transaction before proceeding is configurable
  • 88. Semisynchronous configuration Two plugins implement semisynchronous capability. There is one plugin for the master side and one for the slave side. System variables control plugin behavior. Some examples: rpl_semi_sync_master_enabled Controls whether semisynchronous replication is enabled on the master. To enable or disable the plugin, set this variable to 1 or 0, respectively. The default is 0 (off). rpl_semi_sync_master_timeout A value in milliseconds that controls how long the master waits on a commit for acknowledgment from a slave before timing out and reverting to asynchronous replication. The default value is 10000 (10 seconds). rpl_semi_sync_slave_enabled Similar to rpl_semi_sync_master_enabled, but controls the slave plugin. 88
  • 89. Semisynchronous configuration On the master: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; On each slave: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS -> WHERE PLUGIN_NAME LIKE '%semi%'; +----------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | 89
  • 91. When things go #%^@! 91 If you have followed the instructions but your replication setup is not working, the first thing to do is check the error log for messages. Many users have lost time by not doing this soon enough after encountering problems. If you cannot tell from the error log what the problem was, try the following techniques: Verify that the master has binary logging enabled by issuing a SHOW MASTER STATUS statement. If logging is enabled, Position is nonzero. If binary logging is not enabled, verify that you are running the master with the --log-bin option. Verify that the master and slave both were started with the --server-id option and that the ID value is unique on each server. Verify that the slave is running. Use SHOW SLAVE STATUS to check whether the Slave_IO_Running and Slave_SQL_Running values are both Yes. If not, verify the options that were used when starting the slave server. For example, --skip-slave-start prevents the slave threads from starting until you issue a START SLAVEstatement.
  • 92. When things go #%^@! 92 If the slave is running, check whether it established a connection to the master. Use SHOW PROCESSLIST, find the I/O and SQL threads and check their State column to see what they display. If the I/O thread state says Connecting to master, check the following: o Verify the privileges for the user being used for replication on the master. o Check that the host name of the master is correct and that you are using the correct port to connect to the master. The port used for replication is the same as used for client network communication (the default is 3306). For the host name, ensure that the name resolves to the correct IP address. o Check that networking has not been disabled on the master or slave. Look for the skip-networking option in the configuration file. If present, comment it out or remove it. o If the master has a firewall or IP filtering configuration, ensure that the network port being used for MySQL is not being filtered. o Check that you can reach the master by using ping or traceroute/tracert to reach the host.
  • 93. When things go #%^@! 93 If a statement that succeeded on the master refuses to run on the slave, try the following procedure if it is not feasible to do a full database resynchronization by deleting the slave's databases and copying a new snapshot from the master: 1. Determine whether the affected table on the slave is different from the master table. Try to understand how this happened. Then make the slave's table identical to the master's and run START SLAVE. 2. If the preceding step does not work or does not apply, try to understand whether it would be safe to make the update manually (if needed) and then ignore the next statement from the master. 3. If you decide that the slave can skip the next statement from the master, issue the following statements: 4. mysql> SET GLOBAL sql_slave_skip_counter = N; mysql> START SLAVE; 5. The value of N should be 1 if the next statement from the master does not use AUTO_INCREMENT or
  • 95. Group Replication Group Replication enables you to create fault-tolerant systems with redundancy by replicating the system state throughout a set of servers. Consequently, even if some of the servers fail, as long it is not all or a majority, the system is still available, and all it could have degraded performance or scalability, it is still available. Server failures are isolated and independent. They are tracked by a group membership service which relies on a distributed failure detector that is able to signal when any servers leave the group, either voluntarily or due to an unexpected halt. There is a distributed recovery procedure to ensure that when servers join the group they are brought up to date automatically. There is no need for server fail-over, and the multi-master update everywhere nature ensures that not even updates are blocked in the event of a single server failure. Therefore MySQL Group Replication guarantees that the database service is continuously available. It is important to understand that although the database service is available, in the event of a server crash, those clients connected to it must be redirected, or failed over, to a different server. This is not something Group Replication attempts to resolve. A connector, load balancer, router, or some form of middleware are more suitable to deal with this issue. To summarize, MySQL Group Replication provides a highly available, highly elastic, dependable MySQL service. 95
  • 96. Examples of Use Case Scenarios The following examples are typical use cases for Group Replication. Elastic Replication - Environments that require a very fluid replication infrastructure, where the number of servers has to grow or shrink dynamically and with as few side-effects as possible. For instance, database services for the cloud. Highly Available Shards - Sharding is a popular approach to achieve write scale-out. Use MySQL Group Replication to implement highly available shards, where each shard maps to a replication group. Alternative to Master-Slave replication - In certain situations, using a single master server makes it a single point of contention. Writing to an entire group may prove more scalable under certain circumstances. Autonomic Systems - Additionally, you can deploy MySQL Group Replication purely for the automation that is built into the replication protocol (described already in this and previous chapters). 96
  • 97. Failure Detection There is a failure detection mechanism provided that is able to find and report which servers are silent and as such assumed to be dead. At a high level, the failure detector is a distributed service that provides information about which servers may be dead (suspicions). Later if the group agrees that the suspicions are probably true, then the group decides that a given server has indeed failed. This means that the remaining members in the group take a coordinated decision to exclude a given member. Suspicions are triggered when servers go mute. When server A does not receive messages from server B during a given period, a timeout occurs and a suspicion is raised. If a server gets isolated from the rest of the group, then it suspects that all others have failed. Being unable to secure agreement with the group (as it cannot secure a quorum), its suspicion does not have consequences. When a server is isolated from the group in this way, it is unable to execute any local transactions. 97
  • 98. Group Membership MySQL Group Replication relies on a group membership service. This is built into the plugin. It defines which servers are online and participating in the group. The list of online servers is often referred to as a view. Therefore, every server in the group has a consistent view of which are the members participating actively in the group at a given moment in time. Servers have to agree not only on transaction commits, but also which is the current view. Therefore, if servers agree that a new server becomes part of the group, then the group itself is reconfigured to integrate that server in it, triggering a view change. The opposite also happens, if a server leaves the group, voluntarily or not, then the group dynamically rearranges its configuration and a view change is triggered. Note though that when a member leaves voluntarily, it first initiates a dynamic group reconfiguration. This triggers a procedure, where all members have to agree on the new view without the leaving server. However, if a member leaves involuntarily (for example it has stopped unexpectedly or the network connection is down) then the failure detection mechanism realizes this fact and a reconfiguration of the group is proposed, this one without the failed member. As mentioned this requires agreement from the majority of servers in the group. If the group is not able to reach agreement (for example it partitioned in such a way that there is no majority of servers online), then the system is not be able to dynamically change the configuration and as such, blocks to prevent a split-brain situation. Ultimately, this means that the administrator needs to step in and fix this. 98
  • 99. Fault Tolerance MySQL Group Replication builds on an implementation of the Paxos distributed algorithm to provide distributed coordination between servers. As such, it requires a majority of servers to be active to reach quorum and thus make a decision. This has direct impact on the number of failures the system can tolerate without compromising itself and its overall functionality. The number of servers (n) needed to tolerate f failures is then n = 2 x f + 1. In practice this means that to tolerate one failure the group must have three servers in it. As such if one server fails, there are still two servers to form a majority (two out of three) and allow the system to continue to make decisions automatically and progress. However, if a second server fails involuntarily, then the group (with one server left) blocks, because there is no majority to reach a decision. 99
  • 101. Deploying Instances for Group Replication 101 The first step is to deploy three instances of MySQL Server. Group Replication is a built-in MySQL plugin provided with MySQL Server 5.7.17 and later. For more background information on MySQL plugins, see Section 5.5, “MySQL Server Plugins”. This procedure assumes that MySQL Server was downloaded and unpacked into the directory named mysql-5.7. The following procedure uses one physical machine, therefore each MySQL server instance requires a specific data directory for the instance. Create the data directories in a directory named data and initialize each one. mkdir data mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s1 mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s2 mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s3 Inside data/s1, data/s2, data/s3 is an initialized data directory, containing the mysql system database and related tables and much more. To learn more about the initialization procedure. Note: Do not use --initialize-insecure in production!!!
  • 102. Group Replication Configuration [mysqld] # server configuration datadir=<full_path_to_data>/data/s1 basedir=<full_path_to_bin>/mysql-5.7/ server_id=1 port=24801 socket=<full_path_to_sock_dir>/s1.sock 102 gtid_mode=ON enforce_gtid_consistency=ON master_info_repository=TABLE relay_log_info_repository=TABLE binlog_checksum=NONE log_slave_updates=ON log_bin=binlog binlog_format=ROW transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="aaaaaaaa- aaaa-aaaa-aaaa-aaaaaaaaaaaa" loose-group_replication_start_on_boot=off loose-group_replication_local_address= "127.0.0.1:24901" loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:2490 3" loose-group_replication_bootstrap_group= off
  • 103. Still need a user & start replication mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0,00 sec) mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_pass'; Query OK, 0 rows affected (0,00 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; Query OK, 0 rows affected, 1 warning (0,00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0,00 sec) mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0,00 sec) mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0,01 sec) INSTALL PLUGIN group_replication SONAME 'group_replication.so'; SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL 103
  • 104. Is it running?!?!? mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+------------- +---------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+------------- +---------------+ | group_replication_applier | ce9be252-2b71-11e6-b8f4-00212844f856 | myhost | 24801 | ONLINE | +---------------------------+--------------------------------------+-------------+------------- +---------------+ 1 row in set (0,00 sec) 104
  • 105. Test server! mysql> CREATE DATABASE test; Query OK, 1 row affected (0,00 sec) mysql> use test Database changed mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); Query OK, 0 rows affected (0,00 sec) mysql> INSERT INTO t1 VALUES (1, 'Luis'); Query OK, 1 row affected (0,01 sec) 105
  • 106. Test server! mysql> SELECT * FROM t1; +----+------+ | c1 | c2 | +----+------+ | 1 | Luis | +----+------+ 1 row in set (0,00 sec) 106
  • 107. Test data, review log! mysql> SHOW BINLOG EVENTS; +---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ | binlog.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.17-gr080-log, Binlog ver: 4 | | binlog.000001 | 123 | Previous_gtids | 1 | 150 | | | binlog.000001 | 150 | Gtid | 1 | 211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1' | | binlog.000001 | 211 | Query | 1 | 270 | BEGIN | | binlog.000001 | 270 | View_change | 1 | 369 | view_id=14724817264259180:1 | | binlog.000001 | 369 | Query | 1 | 434 | COMMIT | | binlog.000001 | 434 | Gtid | 1 | 495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2' | | binlog.000001 | 495 | Query | 1 | 585 | CREATE DATABASE test | | binlog.000001 | 585 | Gtid | 1 | 646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3' | | binlog.000001 | 646 | Query | 1 | 770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) | | binlog.000001 | 770 | Gtid | 1 | 831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4' | | binlog.000001 | 831 | Query | 1 | 899 | BEGIN | | binlog.000001 | 899 | Table_map | 1 | 942 | table_id: 108 (test.t1) | | binlog.000001 | 942 | Write_rows | 1 | 984 | table_id: 108 flags: STMT_END_F | | binlog.000001 | 984 | Xid | 1 | 1011 | COMMIT /* xid=38 */ | +---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+ 15 rows in set (0,00 sec) 107
  • 108. Add second server to group! [mysqld] # server configuration datadir=<full_path_to_data>/data/s2 basedir=<full_path_to_bin>/mysql-5.7/ port=24802 socket=<full_path_to_sock_dir>/s2.sock # # Replication configuration parameters # server_id=2 gtid_mode=ON enforce_gtid_consistency=ON master_info_repository=TABLE relay_log_info_repository=TABLE binlog_checksum=NONE log_slave_updates=ON log_bin=binlog binlog_format=ROW # # Group Replication configuration # transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" loose-group_replication_start_on_boot=off loose-group_replication_local_address= "127.0.0.1:24902" loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903" loose-group_replication_bootstrap_group= off 108 SET SQL_LOG_BIN=0; CREATE USER rpl_user@'%'; GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass'; SET SQL_LOG_BIN=1; CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery'; INSTALL PLUGIN group_replication SONAME 'group_replication.so'; START GROUP_REPLICATION;
  • 109. Add second server to group! mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+------------- +---------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+------------- +---------------+ | group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 | myhost | 24801 | ONLINE | | group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 | myhost | 24802 | ONLINE | +---------------------------+--------------------------------------+-------------+------------- +---------------+ 2 rows in set (0,00 sec) 109 Repeat for other servers!
  • 111. Single Primary Mode 111 In this mode the group has a single-primary server that is set to read-write mode. All the other members in the group are set to read-only mode (i.e., super-read-only ). This happens automatically. The primary is typically the first server to boostrap the group, all other servers that join automatically learn about the primary server and are set to read only. When in single-primary mode, some of the checks deployed in multi-primary mode are disabled, because the system enforces that only a single writer server is in the group at a time. For example, changes to tables that have cascading foreign keys are allowed, whereas in multi- primary mode are not. Upon primary member failure, an automatic primary election mechanism chooses the next primary member. The next primary is selected by ordering the remaining servers lexicographically (using their UUID) and picking the first member in the list. In the event the primary member is removed from the group, then an election is performed and a new primary is chosen from the remaining servers in the group. This election is performed by looking at the new view, ordering the server UUIDs in lexicographical order and by picking the first one. Once a new primary is elected, it is automatically set to read-only and the other secondaries remain as secondaries, and as such, read-only. It is a good practice to wait for the new primary to apply its replication related relay-log before re-routing the client applications to it.
  • 113. Multi-Primary Mode 113 In multi-primary mode, there is no notion of a single primary. There is no need to engage an election procedure since there is no server playing any special role. All servers are set to read-write mode when joining the group
  • 114. Partitioning 114 The group needs to achieve consensus whenever a change that needs to be replicated happens. This is the case for regular transactions but is also required for group membership changes and some internal messaging that keeps the group consistent. Consensus requires a majority of group members to agree on a given decision. When a majority of group members is lost, the group is unable to progress and blocks because it cannot secure majority or quorum. Quorum may be lost when there are multiple involuntary failures, causing a majority of servers to be removed abruptly from the group. For example in a group of 5 servers, if 3 of them become silent at once, the majority is compromised and thus no quorum can be achieved. In fact, the remaining two are not able to tell if the other 3 servers have crashed or whether a network partition has isolated these 2 alone and therefore the group cannot be reconfigured automatically. On the other hand, if servers exit the group voluntarily, they instruct the group that it should reconfigure itself. In practice, this means that a server that is leaving tells others that it is going away. This means that other members can reconfigure the group properly, the consistency of the membership is maintained and the majority is recalculated. For example, in the above scenario of 5 servers where 3 leave at once, if the 3 leaving servers warn the group that they are leaving, one by one, then the membership is able to adjust itself from 5 to 2, and at the same time, securing quorum while that happens.
  • 115. Losing majority mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | ONLINE | | group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE | | group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE | | group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | ONLINE | | group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 5 rows in set (0,00 sec) mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | UNREACHABLE | | group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE | | group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE | | group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | UNREACHABLE | | group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | UNREACHABLE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 5 rows in set (0,00 sec) 115
  • 116. Unblocking mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001"; Query OK, 0 rows affected (7,13 sec) mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE | | group_replication_applier | b60907e7-4ab6-11e6-afb7-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 2 rows in set (0,00 sec) 116
  • 117. InnoDB Cluster MySQL InnoDB cluster is a collection of products that work together to provide a complete High Availability solution for MySQL. 117
  • 118. Why InnoDB Cluster A group of MySQL servers can be configured to create a cluster using MySQL Shell. In the default single-primary mode, the cluster of servers has a single read- write primary. Multiple secondary servers are replicas of the primary. Creating a cluster with at least three servers ensures a high availability cluster. A client application is connected to the primary via MySQL Router. If the primary fails, a secondary is automatically promoted to the role of primary, and MySQL Router routes requests to the new primary. Advanced users can also configure a cluster to have multiple-primaries. 118
  • 119. 119
  • 120. 120 MySQL Router MySQL Router is part of InnoDB cluster, and is lightweight middleware that provides transparent routing between your application and back-end MySQL Servers. It can be used for a wide variety of use cases, such as providing high availability and scalability by effectively routing database traffic to appropriate back- end MySQL Servers. The pluggable architecture also enables developers to extend MySQL Router for custom use cases The workflow for using MySQL Router is as follows: 1. MySQL Client or Connector connects to MySQL Router to, for example, port 6446. 2. Router checks for an available MySQL server. 3. Router opens a connection to a suitable MySQL server. 4. Router forwards packets back and forth, between the application and the MySQL server 5. Router disconnects the application if the connected MySQL server fails. The application can then retry connecting to Router, and Router then chooses a different and available MySQL server.
  • 121. ProxySQL Routers Failover Firewall Application Proxy Support many topologies Supports Group Replication 121
  • 123. MTS Multi Threaded Slaves 123 Upto 5.5 Replication was single threaded 5.6 Multi threaded to schema level 5.7 Multi threaded to table level
  • 126. Multi-Source Replication 126 MySQL Multi-Source Replication enables a replication slave to receive transactions from multiple sources simultaneously. Multi- source replication can be used to backup multiple servers to a single server, to merge table shards, and consolidate data from multiple servers to a single server. Multi-source replication does not implement any conflict detection or resolution when applying the transactions, and those tasks are left to the application if required. In a multi-source replication topology, a slave creates a replication channel for each master that it should receive transactions from
  • 127. MSR Status mysql> SELECT * FROM replication_connection_statusG; *************************** 1. row *************************** CHANNEL_NAME: master1 GROUP_NAME: SOURCE_UUID: 046e41f8-a223-11e4-a975-0811960cc264 THREAD_ID: 24 SERVICE_STATE: ON COUNT_RECEIVED_HEARTBEATS: 0 LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00 RECEIVED_TRANSACTION_SET: 046e41f8-a223-11e4-a975-0811960cc264:4-37 LAST_ERROR_NUMBER: 0 LAST_ERROR_MESSAGE: LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00 *************************** 2. row *************************** CHANNEL_NAME: master2 GROUP_NAME: SOURCE_UUID: 7475e474-a223-11e4-a978-0811960cc264 THREAD_ID: 26 SERVICE_STATE: ON COUNT_RECEIVED_HEARTBEATS: 0 LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00 RECEIVED_TRANSACTION_SET: 7475e474-a223-11e4-a978-0811960cc264:4-6 LAST_ERROR_NUMBER: 0 LAST_ERROR_MESSAGE: LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00 2 rows in set (0.00 sec) 127
  • 128. 128