{"action":"created","comment":{"url":"https://api.github.com/repos/tgross/triton-mysql/pulls/comments/47494592","id":47494592,"diff_hunk":"@@ -1,2 +1,66 @@\n # triton-mysql\n-MySQL designed for container-native deployment on Joyent's Triton platform\n+\n+MySQL designed for container-native deployment on Joyent's Triton platform.\n+\n+### Running a new cluster\n+\n+Starting a new cluster is easy. Just run `docker-compose up -d` and in a few moments you'll have a running MySQL primary. Both the primary and replicas are described as a single `docker-compose` service. During startup, [Containerbuddy](http://containerbuddy.io) will ask Consul if an existing primary has been created. If not, the node will initialize as a new primary and all future nodes will self-configure replication with the primary in their `onStart` handler.\n+\n+Run `docker-compose scale mysql=2` to add a replica (or more than one!). Replication in this architecture uses [Global Transaction Idenitifers (GTID)](https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html) rather than binlog positioning as this allows replicas to autoconfigure their position within the binlog. A primary that has the entire execution history can bootstrap a replica with no additional work. The replicas' `onChange` handler will automatically move replication to a new primary if one is created.\n+\n+So long as we're working with a new cluster that has never rotated the binlog on the primary (and where there's not too much data yet), the new replicas will be able to catch up to the primary without further intervention. But if you're bringing up a replica in an existing cluster, you'll need to try the following workflow.\n+\n+### Adding a replica to an existing cluster\n+\n+A primary that has rotated the binlog or simply has a large binlog will be impractical to use to bootstrap replication without copying data first. In this case we're going to [copy the MySQL data directory](https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-failover.html) to the new replica's file system.\n+\n+In order to safely snapshot MySQL, we need to prevent new writes. In order to avoid downtime for the application, we recommend using one of the other replicas as a source for the data directory. The process that's been automated here is as follows:\n+\n+- Write a \"lock\" key to Consul which the replica will look for so that it doesn't complete replication setup until it has the data transfered from the source.\n+- Start a new replica node. The new replica will see there's an existing primary, but will pause the setup process until the lock key has been removed from Consul.\n+- Use `docker exec` to run `STOP SLAVE` on the source node.","path":"README.md","position":22,"original_position":22,"commit_id":"607a54fbfce8cb18cc46a97277c46ab1dca00a72","original_commit_id":"607a54fbfce8cb18cc46a97277c46ab1dca00a72","user":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"body":"> Also note that we'll need to do more than STOP SLAVE. We have to stop the entire mysqld, I think.\r\n\r\nActually it's not `STOP SLAVE` at all. That should read set the source read-only via `SET @@global.read_only = ON;`. Which is enough to make it safe to copy the datadir. The replica isn't running at this point.","created_at":"2015-12-14T13:05:27Z","updated_at":"2015-12-14T13:05:27Z","html_url":"https://github.com/tgross/triton-mysql/pull/1#discussion_r47494592","pull_request_url":"https://api.github.com/repos/tgross/triton-mysql/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/comments/47494592"},"html":{"href":"https://github.com/tgross/triton-mysql/pull/1#discussion_r47494592"},"pull_request":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/tgross/triton-mysql/pulls/1","id":53137722,"html_url":"https://github.com/tgross/triton-mysql/pull/1","diff_url":"https://github.com/tgross/triton-mysql/pull/1.diff","patch_url":"https://github.com/tgross/triton-mysql/pull/1.patch","issue_url":"https://api.github.com/repos/tgross/triton-mysql/issues/1","number":1,"state":"open","locked":false,"title":"Work-in-progress for triton-mysql","user":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"body":"Instances bootstrap themselves via a Containerbuddy `onStart` handler. By using the [GTID replication](http://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html) available in MySQL 5.7, we can avoid having the replica `onStart` manually probing inside the primary in\r\norder to find out the binlog position. Instead the DB will use GTIDs to auto-configure this position.\r\n\r\nThis will work for cases where we're first starting up a cluster -- a replica will go thru as much of the binlog as it needs to catch up on startup. But for starting up instances on an existing cluster with significant data, we'll want to add the ability to migrate a dump of the existing data first.\r\n\r\nTODO:\r\n- [ ] migrating data dumps for new replicas on existing clusters\r\n- [ ] a simple test script to use a mysql client to verify replication is working\r\n\r\ncc @misterbisson @xer0x for comment","created_at":"2015-12-09T15:56:50Z","updated_at":"2015-12-14T13:05:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ae67fdb5a807bc437c0de6ca43d9e2a128222f1d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/tgross/triton-mysql/pulls/1/commits","review_comments_url":"https://api.github.com/repos/tgross/triton-mysql/pulls/1/comments","review_comment_url":"https://api.github.com/repos/tgross/triton-mysql/pulls/comments{/number}","comments_url":"https://api.github.com/repos/tgross/triton-mysql/issues/1/comments","statuses_url":"https://api.github.com/repos/tgross/triton-mysql/statuses/607a54fbfce8cb18cc46a97277c46ab1dca00a72","head":{"label":"tgross:working","ref":"working","sha":"607a54fbfce8cb18cc46a97277c46ab1dca00a72","user":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"repo":{"id":47363306,"name":"triton-mysql","full_name":"tgross/triton-mysql","owner":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tgross/triton-mysql","description":"MySQL designed for container-native deployment on Joyent's Triton platform","fork":false,"url":"https://api.github.com/repos/tgross/triton-mysql","forks_url":"https://api.github.com/repos/tgross/triton-mysql/forks","keys_url":"https://api.github.com/repos/tgross/triton-mysql/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tgross/triton-mysql/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tgross/triton-mysql/teams","hooks_url":"https://api.github.com/repos/tgross/triton-mysql/hooks","issue_events_url":"https://api.github.com/repos/tgross/triton-mysql/issues/events{/number}","events_url":"https://api.github.com/repos/tgross/triton-mysql/events","assignees_url":"https://api.github.com/repos/tgross/triton-mysql/assignees{/user}","branches_url":"https://api.github.com/repos/tgross/triton-mysql/branches{/branch}","tags_url":"https://api.github.com/repos/tgross/triton-mysql/tags","blobs_url":"https://api.github.com/repos/tgross/triton-mysql/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tgross/triton-mysql/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tgross/triton-mysql/git/refs{/sha}","trees_url":"https://api.github.com/repos/tgross/triton-mysql/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tgross/triton-mysql/statuses/{sha}","languages_url":"https://api.github.com/repos/tgross/triton-mysql/languages","stargazers_url":"https://api.github.com/repos/tgross/triton-mysql/stargazers","contributors_url":"https://api.github.com/repos/tgross/triton-mysql/contributors","subscribers_url":"https://api.github.com/repos/tgross/triton-mysql/subscribers","subscription_url":"https://api.github.com/repos/tgross/triton-mysql/subscription","commits_url":"https://api.github.com/repos/tgross/triton-mysql/commits{/sha}","git_commits_url":"https://api.github.com/repos/tgross/triton-mysql/git/commits{/sha}","comments_url":"https://api.github.com/repos/tgross/triton-mysql/comments{/number}","issue_comment_url":"https://api.github.com/repos/tgross/triton-mysql/issues/comments{/number}","contents_url":"https://api.github.com/repos/tgross/triton-mysql/contents/{+path}","compare_url":"https://api.github.com/repos/tgross/triton-mysql/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tgross/triton-mysql/merges","archive_url":"https://api.github.com/repos/tgross/triton-mysql/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tgross/triton-mysql/downloads","issues_url":"https://api.github.com/repos/tgross/triton-mysql/issues{/number}","pulls_url":"https://api.github.com/repos/tgross/triton-mysql/pulls{/number}","milestones_url":"https://api.github.com/repos/tgross/triton-mysql/milestones{/number}","notifications_url":"https://api.github.com/repos/tgross/triton-mysql/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tgross/triton-mysql/labels{/name}","releases_url":"https://api.github.com/repos/tgross/triton-mysql/releases{/id}","created_at":"2015-12-03T21:55:50Z","updated_at":"2015-12-03T21:55:50Z","pushed_at":"2015-12-11T19:24:59Z","git_url":"git://github.com/tgross/triton-mysql.git","ssh_url":"git@github.com:tgross/triton-mysql.git","clone_url":"https://github.com/tgross/triton-mysql.git","svn_url":"https://github.com/tgross/triton-mysql","homepage":null,"size":21,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"tgross:master","ref":"master","sha":"8dee33c41e9138c41709957e1b3e93e39e35dadb","user":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"repo":{"id":47363306,"name":"triton-mysql","full_name":"tgross/triton-mysql","owner":{"login":"tgross","id":1409219,"avatar_url":"https://avatars.githubusercontent.com/u/1409219?v=3","gravatar_id":"","url":"https://api.github.com/users/tgross","html_url":"https://github.com/tgross","followers_url":"https://api.github.com/users/tgross/followers","following_url":"https://api.github.com/users/tgross/following{/other_user}","gists_url":"https://api.github.com/users/tgross/gists{/gist_id}","starred_url":"https://api.github.com/users/tgross/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgross/subscriptions","organizations_url":"https://api.github.com/users/tgross/orgs","repos_url":"https://api.github.com/users/tgross/repos","events_url":"https://api.github.com/users/tgross/events{/privacy}","received_events_url":"https://api.github.com/users/tgross/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tgross/triton-mysql","description":"MySQL designed for container-native deployment on Joyent's Triton platform","fork":false,"url":"https://api.github.com/repos/tgross/triton-mysql","forks_url":"https://api.github.com/repos/tgross/triton-mysql/forks","keys_url":"https://api.github.com/repos/tgross/triton-mysql/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tgross/triton-mysql/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tgross/triton-mysql/teams","hooks_url":"https://api.github.com/repos/tgross/triton-mysql/hooks","issue_events_url":"https://api.github.com/repos/tgross/triton-mysql/issues/events{/number}","events_url":"https://api.github.com/repos/tgross/triton-mysql/events","assignees_url":"https://api.github.com/repos/tgross/triton-mysql/assignees{/user}","branches_url":"https://api.github.com/repos/tgross/triton-mysql/branches{/branch}","tags_url":"https://api.github.com/repos/tgross/triton-mysql/tags","blobs_url":"https://api.github.com/repos/tgross/triton-mysql/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tgross/triton-mysql/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tgross/triton-mysql/git/refs{/sha}","trees_url":"https://api.github.com/repos/tgross/triton-mysql/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tgross/triton-mysql/statuses/{sha}","languages_url":"https://api.github.com/repos/tgross/triton-mysql/languages","stargazers_url":"https://api.github.com/repos/tgross/triton-mysql/stargazers","contributors_url":"https://api.github.com/repos/tgross/triton-mysql/contributors","subscribers_url":"https://api.github.com/repos/tgross/triton-mysql/subscribers","subscription_url":"https://api.github.com/repos/tgross/triton-mysql/subscription","commits_url":"https://api.github.com/repos/tgross/triton-mysql/commits{/sha}","git_commits_url":"https://api.github.com/repos/tgross/triton-mysql/git/commits{/sha}","comments_url":"https://api.github.com/repos/tgross/triton-mysql/comments{/number}","issue_comment_url":"https://api.github.com/repos/tgross/triton-mysql/issues/comments{/number}","contents_url":"https://api.github.com/repos/tgross/triton-mysql/contents/{+path}","compare_url":"https://api.github.com/repos/tgross/triton-mysql/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tgross/triton-mysql/merges","archive_url":"https://api.github.com/repos/tgross/triton-mysql/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tgross/triton-mysql/downloads","issues_url":"https://api.github.com/repos/tgross/triton-mysql/issues{/number}","pulls_url":"https://api.github.com/repos/tgross/triton-mysql/pulls{/number}","milestones_url":"https://api.github.com/repos/tgross/triton-mysql/milestones{/number}","notifications_url":"https://api.github.com/repos/tgross/triton-mysql/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tgross/triton-mysql/labels{/name}","releases_url":"https://api.github.com/repos/tgross/triton-mysql/releases{/id}","created_at":"2015-12-03T21:55:50Z","updated_at":"2015-12-03T21:55:50Z","pushed_at":"2015-12-11T19:24:59Z","git_url":"git://github.com/tgross/triton-mysql.git","ssh_url":"git@github.com:tgross/triton-mysql.git","clone_url":"https://github.com/tgross/triton-mysql.git","svn_url":"https://github.com/tgross/triton-mysql","homepage":null,"size":21,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/1"},"html":{"href":"https://github.com/tgross/triton-mysql/pull/1"},"issue":{"href":"https://api.github.com/repos/tgross/triton-mysql/issues/1"},"comments":{"href":"https://api.github.com/repos/tgross/triton-mysql/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/tgross/triton-mysql/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/tgross/triton-mysql/statuses/607a54fbfce8cb18cc46a97277c46ab1dca00a72"}}}}