Tuesday, 24 February 2015

Repair MySQL Replication slave




If you have set up MySQL replication, you probably know this problem: sometimes there are invalid MySQL queries which cause the replication to not work anymore. In this short guide I explain how you can repair the replication on the MySQL slave without the need to set it up from scratch again.
I do not issue any guarantee that this will work for you!

1 Identifying The Problem

To find out whether replication is/is not working and what has caused to stop it, you can take a look at the logs. On Debian, for example, MySQL logs to/var/log/syslog:
grep mysql /var/log/syslog
server1:/home/admin# grep mysql /var/log/syslog
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'. Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
May 29 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views
May 29 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid', Error_code: 1146
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.001079' position 203015142
server1:/home/admin#
You can see what query caused the error, and at what log position the replication stopped.
To verify that the replication is really not working, log in to MySQL:
mysql -u root -p
On the MySQL shell, run:
mysql> SHOW SLAVE STATUS \G
If one of Slave_IO_Running or Slave_SQL_Running is set to No, then the replication is broken:
mysql> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 1.2.3.4
                Master_User: slave_user
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.001079
        Read_Master_Log_Pos: 269214454
             Relay_Log_File: slave-relay.000130
              Relay_Log_Pos: 100125935
      Relay_Master_Log_File: mysql-bin.001079
           Slave_IO_Running: Yes
          Slave_SQL_Running: No
            Replicate_Do_DB: mydb
        Replicate_Ignore_DB:
         Replicate_Do_Table:
     Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                 Last_Errno: 1146
                 Last_Error: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'.
Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
        SET thread.views = thread.views + aggregate.views
        WHERE thread.threadid = aggregate.threadid'
               Skip_Counter: 0
        Exec_Master_Log_Pos: 203015142
            Relay_Log_Space: 166325247
            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: NULL
1 row in set (0.00 sec)

mysql>

2 Repairing The Replication

Just to go sure, we stop the slave:
mysql> STOP SLAVE;
Fixing the problem is actually quite easy. We tell the slave to simply skip the invalid SQL query:
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
This tells the slave to skip one query (which is the invalid one that caused the replication to stop). If you'd like to skip two queries, you'd use SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; instead and so on.
That's it already. Now we can start the slave again...
mysql> START SLAVE;
... and check if replication is working again:
mysql> SHOW SLAVE STATUS \G
mysql> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 1.2.3.4
                Master_User: slave_user
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.001079
        Read_Master_Log_Pos: 447560366
             Relay_Log_File: slave-relay.000130
              Relay_Log_Pos: 225644062
      Relay_Master_Log_File: mysql-bin.001079
           Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB: mydb
        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
        Exec_Master_Log_Pos: 447560366
            Relay_Log_Space: 225644062
            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
1 row in set (0.00 sec)

mysql>
As you see, both Slave_IO_Running and Slave_SQL_Running are set to Yes now.
Now leave the MySQL shell...
mysql> quit;
... and check the log again:
grep mysql /var/log/syslog
server1:/home/admin# grep mysql /var/log/syslog
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'. Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
May 29 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views
May 29 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid', Error_code: 1146
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.001079' position 203015142
May 29 11:42:13 http2 mysqld[1380]: 080529 11:42:13 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.001079' at position 203015142, relay log '/var/lib/mysql/slave-relay.000130' position: 100125935
server1:/home/admin#

The last line says that replication has started again, and if you see no errors after that line, everything is ok.

How large should be mysql innodb_buffer_pool_size?





up vote31down votefavorite
59
I have a busy database with solely InnoDB tables which is about 5GB in size. The database runs on a Debian server using SSD disks and I've set max connections = 800 which sometimes saturate and grind the server to halt. The average query per second is about 2.5K. So I need to optimize memory usage to make room for maximum possible connections.
I've seen suggestions that innodb_buffer_pool_size should be up to %80 of the total memory. On the other hand I get this warning from tuning-primer script:
Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G
Here are my current innodb variables:
| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |
A side note that might be relevant: I see that when I try to insert a large post (say over 10KB) from Drupal (which sits on a separate web server) to database, it lasts forever and the page does not return correctly.
Regarding these, I'm wondering what should be my innodb_buffer_pool_size for optimal performance. I appreciate your suggestions to set this and other parameters optimally for this scenario.
asked Oct 21 '12 at 15:03

alfish
3592717
add a comment
4 Answers
up vote59down voteaccepted
Your innodb_buffer_pool_size is enormous. You have it set at 20971520000. That's 19.5135 GB. If you only 5GB of InnoDB data and indexes, then you should only have about 8GB. Even this may too high.
Here is what you should do. First run this query
SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;
This will give you the RIBPS, Recommended InnoDB Buffer Pool Size based on all InnoDB Data and Indexes with an additional 60%.
For Example
mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>
With this output, you would set the following in /etc/my.cnf
[mysqld]
innodb_buffer_pool_size=8G
Next, service mysql restart
After the restart, run mysql for a week or two. Then, run this query:
SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;
This will give you how many actual pages of InnoDB data reside in the InnoDB Buffer Pool.
I have written about this before : What to set innodb_buffer_pool and why..?
You could just run this DataGB query right now rather than reconfiguring, restarting and waiting a week.
This value DataGB more closely resembles how big the InnoDB Buffer Pool should be. I am sure this will be far less than the 20000M you have see right now. The savings in RAM can be use for tuning other things like
·         join_buffer_size
·         sort_buffer_size
·         read_buffer_size
·         read_rnd_buffer_size
·         max_connection
CAVEAT #1
This is very important to note : At times, InnoDB may require and additional 10% over the value for theinnodb_buffer_pool_size. Here is what the MySQL Documentation says on this:
The larger you set this value, the less disk I/O is needed to access data in tables. On a dedicated database server, you may set this to up to 80% of the machine physical memory size. Be prepared to scale back this value if these other issues occur:
Competition for physical memory might cause paging in the operating system.
InnoDB reserves additional memory for buffers and control structures, so that the total allocated space is approximately 10% greater than the specified size.
The address space must be contiguous, which can be an issue on Windows systems with DLLs that load at specific addresses.
The time to initialize the buffer pool is roughly proportional to its size. On large installations, this initialization time may be significant. For example, on a modern Linux x86_64 server, initialization of a 10GB buffer pool takes approximately 6 seconds. See Section 8.9.1, “The InnoDB Buffer Pool”.
CAVEAT #2
I See the following values in your my.cnf
| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |
These number will impede InnoDB from accessing multiple cores
Please set the following:
[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64
I have written about this before in the DBA StackExchange
·         Sep 12, 2011 : Possible to make MySQL use more then one core
·         Sep 20, 2011 : Multi cores and MySQL Performance
SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;
answered Oct 22 '12 at 0:30

RolandoMySQLDBA
74.3k1176170
1

My query result times are ridiculous. mysql> SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes FROM information_schema.tables WHERE engine='InnoDB') A; +-------+ | RIBPS | +-------+ | 42 | +-------+ 1 row in set (58.76 sec) The virtualized server has 16GB of allocated RAM. What am I doing wrong? –  user20958 Mar 6 '13 at 22:24 
  

what rationale is there for the "with an additional 60%"? Thanks! –  HTTP500 Nov 12 '13 at 15:56
1

@HTTP500 the 60% is an arbitrary number to accommodate growth. You can pick whatever number you want if you can predict or intelligently guess how much additional growth you expect. That's what the formula says Total_InnoDB_Bytes*1.6 to account for the 60%. If you want 40%, Total_InnoDB_Bytes*1.4– RolandoMySQLDBA Nov 12 '13 at 17:13
  

Figured as much but thanks for the confirmation. –  HTTP500 Nov 12 '13 at 21:26
  

Some people suggest that IOs over 200 are too much unless you have an SSD with much faster write speed. I don't know if they are correct. chriscalender.com/iops-innodb_io_capacity-and-the-innodb-plugin – Buttle Butkus Aug 24 '14 at 2:20

up vote3down vote
Your title asks about innodb_buffer_pool_size, but I suspect that is not the real problem. (Rolando commented on why you have set it big enough, even too big.)
I've set max connections = 800 which sometimes saturate and grind the server to halt.
That is unclear. 800 users in "Sleep" mode has virtually zero impact on the system. 800 active threads would be a disaster. How many threads are "running"?
Are the threads blocking each other? See SHOW ENGINE INNODB STATUS for some clues on deadlocks, etc.
Are any queries showing up in the slowlog? Let's optimize them.
What version are you using? XtraDB (a drop-in replacement for InnoDB) does a better job of using multiple cores. 5.6.7 does an even better job.
innodb_buffer_pool_instances -- change this to 8 (assuming a 20G buffer_pool); it will cut back slightly on the Mutex contention.
Are you I/O bound or are you CPU bound? The solutions are radically different, depending on your answer.
SSD -- It might be better if all the log files were on non-SSD drives.
answered Oct 22 '12 at 23:19

Rick James
2,565610
add a comment
up vote1down vote
More memory is always better, but in my experience most of the times buffer pool size should not fit your data size. Many tables are inactive most of the times, like backup tables lying around, so innodb buffer pool size should rather fit you acive data size.
The time frame you specify for active pages influences the performance, but there's an optimal point, where you won't get that more performance for a bigger buffer size. You could estimate/calculate/measure that by "show engine status innodb".
answered Mar 14 '14 at 10:23

user77376
1184
add a comment


up vote0down vote
Something like this? Using SHOW VARIABLES and SHOW GLOBAL STATUS:
Expression: innodb_buffer_pool_size / _ram
Meaning:
 % of RAM used for InnoDB buffer_pool
Recommended range:
 60~80%

Expression:
 Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
Meaning:
 Read requests that had to hit disk
Recommended range:
 0-2%
What to do if out of range:
 Increase innodb_buffer_pool_size if you have enough RAM.

Expression:
 Innodb_pages_read / Innodb_buffer_pool_read_requests
Meaning:
 Read requests that had to hit disk
Recommended range:
 0-2%
What to do if out of range:
 Increase innodb_buffer_pool_size if you have enough RAM.

Expression:
 Innodb_pages_written / Innodb_buffer_pool_write_requests
Meaning:
 Write requests that had to hit disk 
Recommended range:
 0-15%
What to do if out of range:
 Check innodb_buffer_pool_size

Expression:
 Innodb_buffer_pool_reads / Uptime
Meaning:
 Reads
Recommended range:
 0-100/sec.
What to do if out of range:
 Increase innodb_buffer_pool_size?

Expression:
 (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
Meaning:
 InnoDB I/O
Recommended range:
 0-100/sec.
What to do if out of range:
 Increase innodb_buffer_pool_size?

Expression:
 Innodb_buffer_pool_pages_flushed / Uptime
Meaning:
 Writes (flushes)
Recommended range:
 0-100/sec.
What to do if out of range:
 Increase innodb_buffer_pool_size?

Expression:
 Innodb_buffer_pool_wait_free / Uptime
Meaning:
 Counter for when there are no free pages in buffer_pool. That is, all pages are dirty.
Recommended range:
 0-1/sec.
What to do if out of range:
 First be sure innodb_buffer_pool_size is set reasonably; if still trouble, decrease innodb_max_dirty_pages_pct