{"id":13643050,"url":"https://github.com/Tencent/phxsql","last_synced_at":"2025-04-20T21:32:39.463Z","repository":{"id":47125358,"uuid":"66848830","full_name":"Tencent/phxsql","owner":"Tencent","description":"A high availability MySQL cluster that guarantees data consistency between a master and slaves.","archived":false,"fork":false,"pushed_at":"2018-12-25T10:38:56.000Z","size":852,"stargazers_count":2466,"open_issues_count":47,"forks_count":554,"subscribers_count":266,"default_branch":"master","last_synced_at":"2025-04-14T22:18:25.401Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tencent.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-29T14:02:56.000Z","updated_at":"2025-04-10T11:34:22.000Z","dependencies_parsed_at":"2022-07-21T05:18:21.553Z","dependency_job_id":null,"html_url":"https://github.com/Tencent/phxsql","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tencent%2Fphxsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tencent%2Fphxsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tencent%2Fphxsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tencent%2Fphxsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tencent","download_url":"https://codeload.github.com/Tencent/phxsql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249965547,"owners_count":21352925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:01:40.346Z","updated_at":"2025-04-20T21:32:39.432Z","avatar_url":"https://github.com/Tencent.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"[简体中文README](https://github.com/Tencent/phxsql/blob/master/README.zh_cn.md)\r\n\r\n**PhxSQL is a high-availability and strong-consistency MySQL cluster built on Paxos and Percona.**\r\n\r\nAuthors: Junchao Chen, Haochuan Cui, Duokai Huang, Ming Chen and Sifan Liu \r\n\r\nContact us: phxteam@tencent.com\r\n\r\n[![Build Status](https://travis-ci.org/Tencent/phxsql.svg?branch=master)](https://travis-ci.org/Tencent/phxsql)\r\n\r\n#PhxSQL features:\r\n  - high availability by automatic failovers: the cluster works well when more than half of cluster nodes work and are interconnected.\r\n  - guarantee of data consistency among cluster nodes: replacing loss-less semi-sync between MySQL master and MySQL slaves with Paxos, PhxSQL ensures zero-loss binlogs between master and slaves and supports linearizable consistency, which is as strong as that of Zookeeper.\r\n  - complete compliance with MySQL and MySQL client: PhxSQL supports up to serializable isolation level of transaction.\r\n  - easy deployment and easy maintenance: PhxSQL, powered by in-house implementation of Paxos, has only 4 components including MySQL and doesn't depend on zookeeper or etcd for anything. PhxSql supports automated cluster membership hot reconfiguration.\r\n  \r\n\r\n\r\nThis project includes \r\n* Source codes\r\n* Third party submodules\r\n* Pre-compiled binaries for Ubuntu 64bit system.\r\n    \r\nProjects on which this project depends are also published by Tencent( phxpaxos, phxrpc, libco ).\r\nYou can download or clone them with --recurse-submodule.\r\n\r\n**phxpaxos：** [http://github.com/Tencent/phxpaxos](http://github.com/Tencent/phxpaxos \"http://github.com/Tencent/phxpaxos\")\r\n\r\n**phxrpc：** [http://github.com/Tencent/phxrpc](http://github.com/Tencent/phxrpc \"http://github.com/Tencent/phxrpc\")\r\n\r\n**libco：** [http://github.com/Tencent/libco](http://github.com/Tencent/libco \"http://github.com/Tencent/libco\")\r\n\r\n# Compilation of PhxSQL\r\n\r\n\u003eIf you prefer pre-compiled binaries, just skip this part.\r\n\r\n### Structure of PhxSQL Directories\r\n* PhxSQL\r\n    * phxsqlproxy\r\n    * phxbinlogsvr\r\n    * percona\r\n    * phx_percona\r\n        * plugin\r\n        * phxsync_phxrpc\r\n        * semisync\r\n    * third_party\r\n        * glog\r\n        * leveldb\r\n        * protobuf\r\n        * phxpaxos\r\n        * colib\r\n        * phxrpc\r\n    * tools\r\n    * phxrpc_package_config\r\n\r\n### Introduction of Directories.\r\n\r\n| Name | Introduction |\r\n| ------| ------ |\r\n| phxsqlproxy | surrogate between MySQL client and PhxSql |\r\n| phxbinlogsvr | server for global binlog synchronization and storage, as well as management of mastership and membership |\r\n| percona | Source code of percona5.6.31-77.0 |\r\n| phx_percona/plugin/phxsync_phxrpc | A plugin running in MySql that intercepts MySQL binlogs and forwards them to phxbinlogsvr |\r\n| phx_percona/plugin/semisync | A semisync compatible with our modified plugin APIs of MySQL |\r\n| third_party/glog | GLOG library\r\n| third_party/leveldb | LevelDB library\r\n| third_party/protobuf | Google Protobuf 3.0+ library\r\n| third_party/phxpaxos| PhxPaxos library\r\n| third_party/colib| Libco library\r\n| third_party/phxrpc | Phxrpc library\r\n\r\n\r\n### Preparation\r\n\r\n##### Installation of third party libs\r\n\r\nPhxSQL needs 6 third party libs(glog, leveldb, protobuf, phxpaxos, colib, phxrpc). Please install them in phxsql/third_party directory or just link to third_party.\r\n\r\n**NOTE: Please make sure -fPIC is added while executing configure in GLOG and Protobuf as well as specifying --prefix=/the/current/absolute/path.**\r\n\r\nFor example: `./configure CXXFLAGS=-fPIC --prefix=/home/root/phxsql/third_party/glog`.\r\n\r\n**Then download**  [percona-server-5.6.31-77.0.tar.gz](https://www.percona.com/downloads/Percona-Server-5.6/Percona-Server-5.6.31-77.0/source/tarball/percona-server-5.6.31-77.0.tar.gz)\r\n\r\nMove `percona-server-5.6\\_5.6.31-77.0` to PhxSQL directory, rename or link as 'percona'\r\n**(NOTE: Only percona-server-5.6\\_5.6.31-77.0 is available)**\r\n\r\n\r\n##### Preparation of installation enviroment\r\n1. Execute `./autoinstall.sh \u0026\u0026 make \u0026\u0026 make install`\r\n2. Execute 'make package' to generate a tar.gz package so you can transfer to your target hosts.\r\n\r\n**(NOTE: We put the binaries in install_package/sbin, configuration files in install_package/tools/etc_template, install scripts in install_package/tools. The 'make package' command will pack 'install_package' into 'phxsql-$version.tar.gz'. Please specify -prefix=/the/path/you/want/to/install while executing ./autoinstall.sh)**\r\n\r\n\r\n# Deployment of PhxSQL\r\n\r\n### Host requirements.\r\n\r\n\u003ePhxSQL needs to run on more than 2 hosts. We suggest N \u003e= 3 and N is an odd number, where N means the number of hosts.\r\n\r\n### Initialization of PhxSQL\r\n\r\n1. Transfer phxsql.tar.gz to all of the hosts you want to install. Then do as the following steps:\r\n    1. Execute `tar -xvf phxsq.tar.gz .`\r\n    2. Enter phxsql/tools, Execute `python install.py --help` to get the help of installation.\r\n    \r\n        (For example:`python2.7 install.py -i\"your_inner_ip\" -p 54321 -g 6000 -y 11111 -P 17000 -a 8001 -f/tmp/data/`)\r\n\r\n2.  After executing 'install.py' on all the hosts, Execute './phxbinlogsvr_tools_phxrpc -f InitBinlogSvrMaster -h\"ip1,ip2,ip3\" -p 17000' in any one hosts. 17000 should be replaced with the port on which phxbinlogsvr is listening.\r\n3.  The cluster is active while a message shows master initialization is finished.\r\n4.  You can execute some SQLs to check the status of cluster through `mysql -uroot -h\"your_inner_ip\" -P$phxsqlproxy_port` \r\n\r\n### Simple tests.\r\n\r\n1. Enter phxsql/tools/\r\n2. Execute `test_phxsql.sh phxsqlproxy_port ip1 ip2 ip3`\r\n\r\n### Description of Configuration Files\r\n\r\n\u003e PhxSQL have 3 configuration files in total.\r\n\r\n###### 1. my.cnf： The configuration of MySQL. Please modify it accroding to your own needs.\r\n**NOTE:Modify `tools/etc_temlate/my.cnf` before installation, Modify `etc/my.cnf` after installation**\r\n\r\n###### 2. phxbinlogsvr.conf \r\n\r\n|Section name |Key name |comment|\r\n|------------ | ---------| ------|\r\n|AgentOption | AgentPort | Port for the connection of binlogsvr and MySQL |\r\n| | EventDataDir　|　Directory where to store the binlogsvr data |\r\n| | MaxFileSize　| File size per data of phxbinlogsvr, the unit is B |\r\n| | MasterLease | Lease length of master, the unit is second |\r\n| | CheckPointTime | The data before CheckPointTime will be deleted by phxbinlogsvr, but it will not be deleted if some other PhxSQL nodes have not learned yet, the unit is minute |\r\n| | MaxDeleteCheckPointFileNum　| The maximum number of files deleted each time by phxbinlogsvr |\r\n| | FollowIP | Enabled if it is a follower node and will learn binlog from this `FollowIP`, this node will not vote |\r\n| PaxosOption| PaxosLogPath| Directory where to store paxos data |\r\n| | PaxosPort| Port for paxos to connect each other |\r\n| | PacketMode | The maximum size of paxos log for PhxPaxos,1 means 100M, but the network timeout will be 1 minute, 0 means 50M and network timeout is 2s(changed in dynamic).| \r\n| | UDPMaxSize | Our default network use udp and tcp combination, a message we use udp or tcp to send decide by a threshold. Message size under UDPMaxSize we use udp to send. |\r\n| Server | IP | IP for phxbinlogsvr to listen |\r\n| | Port | Port for phxbinlogsvr to listen |\r\n| |  LogFilePath | Directory to store log |\r\n| | LogLevel | Log level of phxbinlogsvr |\r\n\r\n###### 3. phxsqlproxy.conf \r\n\r\n| Section name | Key name | comment |\r\n| ------| ------| ------|\r\n|Server | IP | IP for phxsqlproxy to listen |\r\n| | Port | Port for phxsqlproxy to listen |\r\n| | LogFilePath  | Directory to store log |\r\n| | LogLevel | Log level of phxbinlogsvr |\r\n| | MasterEnableReadPort | Enable readonly-port in master node. If set to 0, master will forwarding readonly-port requests to one of slaves. |\r\n| | TryBestIfBinlogsvrDead | After the local phxbinlogsvr is dead, phxsqlproxy will try to get master information from phxbinlogsvr on other machine, if this option set to 1. |\r\n\r\n# PhxSQL Usasge\r\n\r\n\u003e phxsqlproxy is the surrogate of PhxSQL, all requests will be sent to phxsqlproxy and then be forwarded to MySQL.\r\n\u003e\r\n### phxsqlproxy provides 2 different types of port for user. \r\n\r\n##### Master Port( also called Read-Write Port )\r\n\r\nIt is the port configured in `phxsqlproxy.conf`.\r\nEvery requests sent to this port will be forwarded to the master node to excute.\r\n\r\n##### Slave Port( also called Read-Only Port )\r\n\r\nIt is (MasterPort + 1). You can also specify it by setting `SlavePort = xxxxx` in `phxsqlproxy.conf`.  \r\nEvery requests will be executed on the local MySQL. A master node will make a redirection to another slave nodes if  `MasterEnableReadPort = 0` (this will save the CPU/IO resource for write requests)\r\n\r\n\r\n### SQL Command Execution\r\n\r\n1. Using `mysql -u$user -h$phxsqlproxyip -P$phxsqlproxyport -p$pwd` to connect to phxsqlproxy\r\n2. Execute SQL command.\r\n\r\n\u003e`$phxsqlproxyip` can be any one IP of hosts in a clusters and `$phxsqlproxyport` can be `MasterPort` or `SlavePort`.\r\n\r\n# PhxSQL Management\r\n\r\nPhxSQL provides a tool `phxbinlogsvr_tools_phxrpc` to help the mangerment of PhxSQL.\r\n\r\nPhxSQL cluster needs 1 MySQL admin accounts and 1 synchronization account. The default admin account is (`root`, `\"\"` ),  the default synchronization account is ( `replica`, `replica123` ), They can be modified( and only be modifyed ) via `phxbinlogsvr_tools_phxrpc`. **DON'T DO THIS MANUALLY.**\r\n\r\n**Following is some commands you may used frequently.**\r\n\r\n### `phxbinlogsvr_tools -f GetMasterInfoFromGlobal -h \u003chost\u003e -p \u003cport\u003e`\r\n\r\n**Function:**Get the current master info from quorum nodes( IP and timeout ).\r\n\r\n**Arguments:**\r\n \r\n  - **Host:** Any one IP of clusters nodes\r\n  - **Port:** Port which phxbinlogsvr is listening. like `17000` \r\n \r\n### `phxbinlogsvr_tools -f SetMySqlAdminInfo -h \u003chost\u003e -p \u003cport\u003e -u \u003cadmin username\u003e -d \u003cadmin pwd\u003e -U \u003cnew admin username\u003e -D \u003cnew admin pwd\u003e`\r\n\r\n**Function:** Set the user and password of admin account.\r\n\r\n**Arguments:**\r\n\r\n  - **Host:** Any one IP of clusters nodes\r\n  - **Port:** Port which phxbinlogsvr is listening. like `17000`\r\n  - **Admin username:** Current account user( default is `root` )\r\n  - **Admin pwd:** Current account password( default is `\"\"` )\r\n  - **New admin username:** New user\r\n  - **New admin pwd:** New password\r\n\r\n### `phxbinlogsvr_tools -f SetMySqlReplicaInfo -h \u003chost\u003e -p \u003cport\u003e -u \u003cadmin username\u003e -d \u003cadmin pwd\u003e -U \u003cnew replica username\u003e -D \u003cnew replica pwd\u003e`\r\n\r\n**Function:** Set the user and password of synchronization account.\r\n\r\n**Arguments：**\r\n\r\n  - **Host:** Any one IP of clusters nodes\r\n  - **Port:** Port which phxbinlogsvr is listening. like `17000`\r\n  - **Admin username:** Current account user( default is `root` )\r\n  - **Admin pwd:** Current account password( default is `\"\"` )\r\n  - **New replica username:**  New user\r\n  - **New replica pwd:** New password\r\n \r\n### `phxbinlogsvr_tools_phxrpc -f GetMemberList -h \u003chost\u003e -p \u003cport\u003e`\r\n\r\n**Function:** Membership of this cluster, all IPs and Ports included.\r\n\r\n**Arguments:**\r\n \r\n  - **Host:** Any one IP of clusters nodes\r\n  - **Port:** Port which phxbinlogsvr is listening. like `17000`\r\n\r\n# Phxbinlogsvr Membership Managerment\r\n\r\n### Member Deletion\r\nExecute `phxbinlogsvr_tools_phxrpc -f RemoveMember -h\u003chost\u003e -p\u003cport\u003e -m \u003cip_of_nodeA\u003e` to delete node A.\r\nOnce it is succesfully executed, A will not learn binlog after a small period.\r\n\r\n### Member Involvement\r\n1. Execute `phxbinlogsvr_tools -f AddMember -h\u003chost\u003e -p\u003cport\u003e -m \u003cip_of_nodeA\u003e` to add node A into the membership.\r\n2. Install PhxSQL on A.\r\n3. A will begin to learn data after installation is finished.\r\n4. Copy a snapshot of MySQL from any other nodes to A.\r\n5. Kill phxbinlogsvr and access MySQL through the local port( or socket ). then execute `set global super_read_only = 0; set global read_only = 0`;\r\n6. Dump the snapshot into MySQL.\r\n7. A will begin to work after a while.\r\n\r\n# Phxbinlogsvr fault Handling.\r\n\r\n###### You can choose to reinstall PhxSQL if PhxSQL meets an unrecovery failure.\r\n\r\n`Phxbinlogsvr` will pull the checkpoint in another node to reboot during reinstallation. It will self-kill after pulling is over(to make sure the consistency). You can reboot `phxbinlogsvr` after a message like `\"All sm load state ok, start to exit\"` appears. \r\n\r\n###### `phxbinlogsvr` will stop working if a data problem arise in MySQL. We suggest you to check the status of MySQL. \r\n###### You can observe logs with red `\"err\"` to check the abnormaly. \r\n\r\n# Performance Testing\r\n\r\n### Hosts Infomation\t\r\nCPU :\tIntel(R) Xeon(R) CPU E5-2420 0 @ 1.90GHz * 24\r\n\r\nMemory : 32G\r\n\r\nDisk : SSD Raid10 \r\n\r\n\r\n### Ping Costs\r\nMaster -\u003e Slave : 3 ~ 4ms\r\n\r\nClient -\u003e Master : 4ms\r\n\r\n\r\n### Tools and Arguments\r\nsysbench  --oltp-tables-count=10 --oltp-table-size=1000000 --num-threads=500 --max-requests=100000 --report-interval=1 --max-time=200\r\n\r\n### Results\r\n\r\n\r\n| Client Threads                                         | Clusters    |                    |             |     Test sets   |           |                 |               |\r\n|------------------------------------------------------|-------------|------------------------|-------------|----------------------|-----------|---------------------|---------------|\r\n|                                                      |             | insert.lua (100% write)     |             | select.lua (0% write)     |           | OLTP.lua (20% write)     |               |\r\n|                                                      |             | QPS                | Response time(MS)        | QPS              | Response time(MS)      | QPS             | Response time(MS)          |\r\n| 200                                                  | PhxSQL      | 5076               | 39.34/56.93 | 46334            | 4.21/5.12 | 25657           | 140.16/186.39 |\r\n| 200                                                  | MySQL semi-sync | 4055               | 49.27/66.64 | 47528            | 4.10/5.00 | 20391           | 176.39/226.76 |\r\n| 500                                                  | PhxSQL      | 8260               | 60.41/83.14 | 105928           | 4.58/5.81 | 46543           | 192.93/242.85 |\r\n| 500                                                  | MySQL semi-sync | 7072               | 70.60/91.72 | 121535           | 4.17/5.08 | 33229           | 270.38/345.84 |\r\n\r\n**NOTE:The 2 Response times means average and 95% percentile**\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTencent%2Fphxsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTencent%2Fphxsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTencent%2Fphxsql/lists"}