{"id":4915,"date":"2012-07-04T10:00:24","date_gmt":"2012-07-04T08:00:24","guid":{"rendered":"http:\/\/code.openark.org\/blog\/?p=4915"},"modified":"2012-07-04T10:00:24","modified_gmt":"2012-07-04T08:00:24","slug":"notes-on-row-based-replication","status":"publish","type":"post","link":"https:\/\/code.openark.org\/blog\/mysql\/notes-on-row-based-replication","title":{"rendered":"Notes on row based replication"},"content":{"rendered":"<p>MySQL&#8217;s <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.1\/en\/replication-formats.html\">Row Based Replication<\/a> (RBR) succeeds (though not replaces) Statement Based Replication (SBR), as of version <strong>5.1<\/strong>.<\/p>\n<p>Anyone who is familiar with replication data drift &#8212; the unexplained growing data difference between master &amp; slave &#8212; might wish to look into row based replication. On multiple servers I&#8217;m handling the change to RBR has eliminated (to the best of my findings) replication data drift.<\/p>\n<p>This is easily explained, as RBR writes particular row IDs into the binary log. You no longer need to hope the statement<\/p>\n<blockquote>\n<pre>DELETE FROM my_table ORDER BY my_column LIMIT 100<\/pre>\n<\/blockquote>\n<p>acts deterministically on all servers (is <strong>my_column<\/strong> UNIQUE?). With row based replication the particular rows deleted on the master are then deleted on the slave.<\/p>\n<p>Here are three notes on RBR:<!--more--><\/p>\n<ul>\n<li><em>Binary log size:<\/em><\/li>\n<\/ul>\n<p style=\"padding-left: 30px;\">With statement based replication the binary log merely logs the statement &#8211; typically a short text. But RBR logs the row IDs and changes made to data.<\/p>\n<p style=\"padding-left: 30px;\">After we finally got used to cheap huge disks, and forgot about the need for cleaning up the binary logs, RBR introduces bloated logs. On some servers I&#8217;am again confounded by the fact that <strong>3<\/strong> days worth of logs will hog my entire disk space.<\/p>\n<ul>\n<li><em>Forgiveness<\/em><\/li>\n<\/ul>\n<p style=\"padding-left: 30px;\">RBR is not as forgiving as SBR. With SBR, you could <strong>DELETE<\/strong> some rows from the master. If they&#8217;re already missing on the slave, no problem here. With RBR, such an incident makes for replication failure (RBR: <em>&#8220;I&#8217;m supposed to DELETE rows 3, 4, 5 but can&#8217;t find them! I can&#8217;t to my job like this! Heeelp!&#8221;<\/em>)<\/p>\n<p style=\"padding-left: 30px;\">This is not a bad thing: you get an early alert that <em>something went wrong<\/em>.<\/p>\n<ul>\n<li><em>Less slave effort<\/em><\/li>\n<\/ul>\n<p style=\"padding-left: 30px;\">On the up side, the slave does not need to do much thinking. Given a DELETE command, the slave does not need to look up those rows <strong>WHERE some_condition IS TRUE<\/strong>. Instead, the master does all the hard work, the slave just gets the IDs of rows to delete.<\/p>\n<p style=\"padding-left: 30px;\">I find that this boosts up replication speed in some scenarios, and in particular the scenario of data cleanup: those nightly\/weekly purging of old, unused data. If you look hard and all you find are <strong>5<\/strong> rows to delete, all the slave needs to do is to delete those indicated <strong>5<\/strong> rows. With single-threaded replication this makes a real difference.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>MySQL&#8217;s Row Based Replication (RBR) succeeds (though not replaces) Statement Based Replication (SBR), as of version 5.1. Anyone who is familiar with replication data drift &#8212; the unexplained growing data difference between master &amp; slave &#8212; might wish to look into row based replication. On multiple servers I&#8217;m handling the change to RBR has eliminated [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[5],"tags":[8],"class_list":["post-4915","post","type-post","status-publish","format-standard","hentry","category-mysql","tag-replication"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2bZZp-1hh","_links":{"self":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/4915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/comments?post=4915"}],"version-history":[{"count":18,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/4915\/revisions"}],"predecessor-version":[{"id":5042,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/4915\/revisions\/5042"}],"wp:attachment":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/media?parent=4915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/categories?post=4915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/tags?post=4915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}