{"action":"created","comment":{"url":"https://api.github.com/repos/pingcap/dm/pulls/comments/283206544","pull_request_review_id":236499793,"id":283206544,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI4MzIwNjU0NA==","diff_hunk":"@@ -0,0 +1,43 @@\n+// Copyright 2019 PingCAP, Inc.\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+package binlog\n+\n+import (\n+\t\"strconv\"\n+\t\"strings\"\n+\n+\t\"github.com/pingcap/errors\"\n+)\n+\n+const (\n+\t// the binlog file name format is `base + '.' + seq`.\n+\tbinlogFilenameSep = \".\"\n+)\n+\n+var (\n+\t// ErrInvalidBinlogFilename means error about invalid binlog filename.\n+\tErrInvalidBinlogFilename = errors.New(\"invalid binlog filename\")\n+)\n+\n+// VerifyBinlogFilename verify whether is a valid MySQL/MariaDB binlog filename.\n+// valid format is `base + '.' + seq`.\n+func VerifyBinlogFilename(filename string) error {\n+\tparts := strings.Split(filename, binlogFilenameSep)\n+\tif len(parts) != 2 {\n+\t\treturn errors.Annotatef(ErrInvalidBinlogFilename, \"filename %s\", filename)\n+\t} else if _, err := strconv.Atoi(parts[1]); err != nil {","path":"pkg/binlog/filename.go","position":39,"original_position":39,"commit_id":"63d1b7b34db6725f5746ebfc85b136157da1bb11","original_commit_id":"63d1b7b34db6725f5746ebfc85b136157da1bb11","user":{"login":"amyangfei","id":1527315,"node_id":"MDQ6VXNlcjE1MjczMTU=","avatar_url":"https://avatars0.githubusercontent.com/u/1527315?v=4","gravatar_id":"","url":"https://api.github.com/users/amyangfei","html_url":"https://github.com/amyangfei","followers_url":"https://api.github.com/users/amyangfei/followers","following_url":"https://api.github.com/users/amyangfei/following{/other_user}","gists_url":"https://api.github.com/users/amyangfei/gists{/gist_id}","starred_url":"https://api.github.com/users/amyangfei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amyangfei/subscriptions","organizations_url":"https://api.github.com/users/amyangfei/orgs","repos_url":"https://api.github.com/users/amyangfei/repos","events_url":"https://api.github.com/users/amyangfei/events{/privacy}","received_events_url":"https://api.github.com/users/amyangfei/received_events","type":"User","site_admin":false},"body":"seems not check binlog filename like `mysql-bin.-1000`","created_at":"2019-05-13T06:54:25Z","updated_at":"2019-05-13T06:54:25Z","html_url":"https://github.com/pingcap/dm/pull/117#discussion_r283206544","pull_request_url":"https://api.github.com/repos/pingcap/dm/pulls/117","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/pingcap/dm/pulls/comments/283206544"},"html":{"href":"https://github.com/pingcap/dm/pull/117#discussion_r283206544"},"pull_request":{"href":"https://api.github.com/repos/pingcap/dm/pulls/117"}}},"pull_request":{"url":"https://api.github.com/repos/pingcap/dm/pulls/117","id":271606897,"node_id":"MDExOlB1bGxSZXF1ZXN0MjcxNjA2ODk3","html_url":"https://github.com/pingcap/dm/pull/117","diff_url":"https://github.com/pingcap/dm/pull/117.diff","patch_url":"https://github.com/pingcap/dm/pull/117.patch","issue_url":"https://api.github.com/repos/pingcap/dm/issues/117","number":117,"state":"open","locked":false,"title":"*: add `Writer` for relay log","user":{"login":"csuzhangxc","id":3183039,"node_id":"MDQ6VXNlcjMxODMwMzk=","avatar_url":"https://avatars0.githubusercontent.com/u/3183039?v=4","gravatar_id":"","url":"https://api.github.com/users/csuzhangxc","html_url":"https://github.com/csuzhangxc","followers_url":"https://api.github.com/users/csuzhangxc/followers","following_url":"https://api.github.com/users/csuzhangxc/following{/other_user}","gists_url":"https://api.github.com/users/csuzhangxc/gists{/gist_id}","starred_url":"https://api.github.com/users/csuzhangxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csuzhangxc/subscriptions","organizations_url":"https://api.github.com/users/csuzhangxc/orgs","repos_url":"https://api.github.com/users/csuzhangxc/repos","events_url":"https://api.github.com/users/csuzhangxc/events{/privacy}","received_events_url":"https://api.github.com/users/csuzhangxc/received_events","type":"User","site_admin":false},"body":"<!--\r\nThank you for contributing to DM! Please read MD's [CONTRIBUTING](https://github.com/pingcap/dm/blob/master/CONTRIBUTING.md) document **BEFORE** filing this PR.\r\n-->\r\n\r\n### What problem does this PR solve? <!--add issue link with summary if exists-->\r\n\r\nthis PR is a part of #91.\r\n\r\n### What is changed and how it works?\r\n\r\n- add a `FileWriter` to support to write binlog events into files\r\n\t- write a binlog file header for any new binlog file\r\n\t- ignore any fake `RotateEvent`\r\n\t- ignore any duplicate events\r\n\t- fill any potential holes in the binlog file with dummy events\r\n- The `FileWriter` support to recover any binlog file with uncompleted events/transactions\r\n\r\n### Check List <!--REMOVE the items that are not applicable-->\r\n\r\nTests <!-- At least one of them must be included. -->\r\n\r\n - Unit test\r\n\r\nCode changes\r\n\r\n - Has exported function/method change\r\n - Has exported variable/fields change\r\n - Has interface methods change\r\n\r\nSide effects\r\n\r\n - Increased code complexity\r\n","created_at":"2019-04-18T09:03:13Z","updated_at":"2019-05-13T06:54:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2a2ffd1d59d50eea196302775f3c63e2b4c657bb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1195099888,"node_id":"MDU6TGFiZWwxMTk1MDk5ODg4","url":"https://api.github.com/repos/pingcap/dm/labels/priority/important","name":"priority/important","color":"b60205","default":false},{"id":1196629689,"node_id":"MDU6TGFiZWwxMTk2NjI5Njg5","url":"https://api.github.com/repos/pingcap/dm/labels/status/PTAL","name":"status/PTAL","color":"2cbe4e","default":false},{"id":1196631541,"node_id":"MDU6TGFiZWwxMTk2NjMxNTQx","url":"https://api.github.com/repos/pingcap/dm/labels/type/enhancement","name":"type/enhancement","color":"f2dc8c","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/pingcap/dm/pulls/117/commits","review_comments_url":"https://api.github.com/repos/pingcap/dm/pulls/117/comments","review_comment_url":"https://api.github.com/repos/pingcap/dm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pingcap/dm/issues/117/comments","statuses_url":"https://api.github.com/repos/pingcap/dm/statuses/63d1b7b34db6725f5746ebfc85b136157da1bb11","head":{"label":"csuzhangxc:relay-writer-2","ref":"relay-writer-2","sha":"63d1b7b34db6725f5746ebfc85b136157da1bb11","user":{"login":"csuzhangxc","id":3183039,"node_id":"MDQ6VXNlcjMxODMwMzk=","avatar_url":"https://avatars0.githubusercontent.com/u/3183039?v=4","gravatar_id":"","url":"https://api.github.com/users/csuzhangxc","html_url":"https://github.com/csuzhangxc","followers_url":"https://api.github.com/users/csuzhangxc/followers","following_url":"https://api.github.com/users/csuzhangxc/following{/other_user}","gists_url":"https://api.github.com/users/csuzhangxc/gists{/gist_id}","starred_url":"https://api.github.com/users/csuzhangxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csuzhangxc/subscriptions","organizations_url":"https://api.github.com/users/csuzhangxc/orgs","repos_url":"https://api.github.com/users/csuzhangxc/repos","events_url":"https://api.github.com/users/csuzhangxc/events{/privacy}","received_events_url":"https://api.github.com/users/csuzhangxc/received_events","type":"User","site_admin":false},"repo":{"id":166750244,"node_id":"MDEwOlJlcG9zaXRvcnkxNjY3NTAyNDQ=","name":"dm","full_name":"csuzhangxc/dm","private":false,"owner":{"login":"csuzhangxc","id":3183039,"node_id":"MDQ6VXNlcjMxODMwMzk=","avatar_url":"https://avatars0.githubusercontent.com/u/3183039?v=4","gravatar_id":"","url":"https://api.github.com/users/csuzhangxc","html_url":"https://github.com/csuzhangxc","followers_url":"https://api.github.com/users/csuzhangxc/followers","following_url":"https://api.github.com/users/csuzhangxc/following{/other_user}","gists_url":"https://api.github.com/users/csuzhangxc/gists{/gist_id}","starred_url":"https://api.github.com/users/csuzhangxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csuzhangxc/subscriptions","organizations_url":"https://api.github.com/users/csuzhangxc/orgs","repos_url":"https://api.github.com/users/csuzhangxc/repos","events_url":"https://api.github.com/users/csuzhangxc/events{/privacy}","received_events_url":"https://api.github.com/users/csuzhangxc/received_events","type":"User","site_admin":false},"html_url":"https://github.com/csuzhangxc/dm","description":"Data Migration Platform","fork":true,"url":"https://api.github.com/repos/csuzhangxc/dm","forks_url":"https://api.github.com/repos/csuzhangxc/dm/forks","keys_url":"https://api.github.com/repos/csuzhangxc/dm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/csuzhangxc/dm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/csuzhangxc/dm/teams","hooks_url":"https://api.github.com/repos/csuzhangxc/dm/hooks","issue_events_url":"https://api.github.com/repos/csuzhangxc/dm/issues/events{/number}","events_url":"https://api.github.com/repos/csuzhangxc/dm/events","assignees_url":"https://api.github.com/repos/csuzhangxc/dm/assignees{/user}","branches_url":"https://api.github.com/repos/csuzhangxc/dm/branches{/branch}","tags_url":"https://api.github.com/repos/csuzhangxc/dm/tags","blobs_url":"https://api.github.com/repos/csuzhangxc/dm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/csuzhangxc/dm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/csuzhangxc/dm/git/refs{/sha}","trees_url":"https://api.github.com/repos/csuzhangxc/dm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/csuzhangxc/dm/statuses/{sha}","languages_url":"https://api.github.com/repos/csuzhangxc/dm/languages","stargazers_url":"https://api.github.com/repos/csuzhangxc/dm/stargazers","contributors_url":"https://api.github.com/repos/csuzhangxc/dm/contributors","subscribers_url":"https://api.github.com/repos/csuzhangxc/dm/subscribers","subscription_url":"https://api.github.com/repos/csuzhangxc/dm/subscription","commits_url":"https://api.github.com/repos/csuzhangxc/dm/commits{/sha}","git_commits_url":"https://api.github.com/repos/csuzhangxc/dm/git/commits{/sha}","comments_url":"https://api.github.com/repos/csuzhangxc/dm/comments{/number}","issue_comment_url":"https://api.github.com/repos/csuzhangxc/dm/issues/comments{/number}","contents_url":"https://api.github.com/repos/csuzhangxc/dm/contents/{+path}","compare_url":"https://api.github.com/repos/csuzhangxc/dm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/csuzhangxc/dm/merges","archive_url":"https://api.github.com/repos/csuzhangxc/dm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/csuzhangxc/dm/downloads","issues_url":"https://api.github.com/repos/csuzhangxc/dm/issues{/number}","pulls_url":"https://api.github.com/repos/csuzhangxc/dm/pulls{/number}","milestones_url":"https://api.github.com/repos/csuzhangxc/dm/milestones{/number}","notifications_url":"https://api.github.com/repos/csuzhangxc/dm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/csuzhangxc/dm/labels{/name}","releases_url":"https://api.github.com/repos/csuzhangxc/dm/releases{/id}","deployments_url":"https://api.github.com/repos/csuzhangxc/dm/deployments","created_at":"2019-01-21T04:52:12Z","updated_at":"2019-05-13T06:38:52Z","pushed_at":"2019-05-13T06:43:50Z","git_url":"git://github.com/csuzhangxc/dm.git","ssh_url":"git@github.com:csuzhangxc/dm.git","clone_url":"https://github.com/csuzhangxc/dm.git","svn_url":"https://github.com/csuzhangxc/dm","homepage":"","size":6457,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"pingcap:master","ref":"master","sha":"adbb4c11567d17e0a644c09cdac2eff22afd8c4c","user":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"repo":{"id":165957180,"node_id":"MDEwOlJlcG9zaXRvcnkxNjU5NTcxODA=","name":"dm","full_name":"pingcap/dm","private":false,"owner":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/pingcap/dm","description":"Data Migration Platform","fork":false,"url":"https://api.github.com/repos/pingcap/dm","forks_url":"https://api.github.com/repos/pingcap/dm/forks","keys_url":"https://api.github.com/repos/pingcap/dm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingcap/dm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingcap/dm/teams","hooks_url":"https://api.github.com/repos/pingcap/dm/hooks","issue_events_url":"https://api.github.com/repos/pingcap/dm/issues/events{/number}","events_url":"https://api.github.com/repos/pingcap/dm/events","assignees_url":"https://api.github.com/repos/pingcap/dm/assignees{/user}","branches_url":"https://api.github.com/repos/pingcap/dm/branches{/branch}","tags_url":"https://api.github.com/repos/pingcap/dm/tags","blobs_url":"https://api.github.com/repos/pingcap/dm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingcap/dm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingcap/dm/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingcap/dm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingcap/dm/statuses/{sha}","languages_url":"https://api.github.com/repos/pingcap/dm/languages","stargazers_url":"https://api.github.com/repos/pingcap/dm/stargazers","contributors_url":"https://api.github.com/repos/pingcap/dm/contributors","subscribers_url":"https://api.github.com/repos/pingcap/dm/subscribers","subscription_url":"https://api.github.com/repos/pingcap/dm/subscription","commits_url":"https://api.github.com/repos/pingcap/dm/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingcap/dm/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingcap/dm/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingcap/dm/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingcap/dm/contents/{+path}","compare_url":"https://api.github.com/repos/pingcap/dm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingcap/dm/merges","archive_url":"https://api.github.com/repos/pingcap/dm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingcap/dm/downloads","issues_url":"https://api.github.com/repos/pingcap/dm/issues{/number}","pulls_url":"https://api.github.com/repos/pingcap/dm/pulls{/number}","milestones_url":"https://api.github.com/repos/pingcap/dm/milestones{/number}","notifications_url":"https://api.github.com/repos/pingcap/dm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingcap/dm/labels{/name}","releases_url":"https://api.github.com/repos/pingcap/dm/releases{/id}","deployments_url":"https://api.github.com/repos/pingcap/dm/deployments","created_at":"2019-01-16T02:13:45Z","updated_at":"2019-05-13T05:57:53Z","pushed_at":"2019-05-13T06:43:51Z","git_url":"git://github.com/pingcap/dm.git","ssh_url":"git@github.com:pingcap/dm.git","clone_url":"https://github.com/pingcap/dm.git","svn_url":"https://github.com/pingcap/dm","homepage":"","size":6361,"stargazers_count":230,"watchers_count":230,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":57,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":26,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":57,"open_issues":26,"watchers":230,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pingcap/dm/pulls/117"},"html":{"href":"https://github.com/pingcap/dm/pull/117"},"issue":{"href":"https://api.github.com/repos/pingcap/dm/issues/117"},"comments":{"href":"https://api.github.com/repos/pingcap/dm/issues/117/comments"},"review_comments":{"href":"https://api.github.com/repos/pingcap/dm/pulls/117/comments"},"review_comment":{"href":"https://api.github.com/repos/pingcap/dm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pingcap/dm/pulls/117/commits"},"statuses":{"href":"https://api.github.com/repos/pingcap/dm/statuses/63d1b7b34db6725f5746ebfc85b136157da1bb11"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"amyangfei"}}