PHP-Sharding-PDO: splitting MySQL tables behind a PDO-shaped API
PHP、MySQL分库分表中间件,需要依赖PDO,PHP分库分表,支持协程(PHP, MySQL sharding library and sharding table middleware, need to rely on PDO, support coroutines.)
At a glance
- What is it?
- PHP-Sharding-PDO is a PHP and MySQL sharding middleware that sits on top of PDO, routes queries to a database and table based on configurable rules, and supports coroutine environments through Swoole. It fits a team that must shard an existing PHP codebase, and its own documentation is blunt about the failure modes of that.
- Who is it for?
- PHP-Sharding-PDO fits a team that already depends on PDO, needs to split MySQL tables across databases without rewriting its data access code, and can accept the rules being defined in PHP rather than in configuration files.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 120 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A middleware that keeps the PDO call shape
PHP-Sharding-PDO describes itself as a PHP and MySQL sharding library that depends on PDO and supports coroutines, and that dependency on PDO is the commercial case for it. A team that has a working PHP application on PDO can introduce sharding behind the same call shape rather than replacing its data access layer with a different abstraction. The library is a middleware, which means it decides, for each query, which physical database and which physical table the statement lands on. That decision is not hidden from you, it is the central configuration object, and the repository ships tests and examples that show the rules being declared in a class. The environment requirements are modest, PHP 7.2 or newer, and Swoole 4.1.0 or newer if you run in a coroutine environment. The package is Apache-2.0 licensed and lives under the vendor name lys, with the source under src/ and the test suite under tests/ alongside a RECORD.md and both English and Chinese readmes.
Sharding rules are declared in a PHP class, not in a config file
The configuration surface is a class you extend, which is the design decision most likely to matter to a PHP team. The example configuration imports the rule and strategy types from the PhpShardingPdo namespaces and extends ShardingInitConfigInter.
namespace PhpShardingPdo\Test;
use PhpShardingPdo\Common\ConfigEnv;
use PhpShardingPdo\Core\ShardingTableRuleConfig;
use PhpShardingPdo\Core\InlineShardingStrategyConfiguration;
use PhpShardingPdo\Core\ShardingPdoContext;
use PhpShardingPdo\Core\ShardingRuleConfiguration;
use PhpShardingPdo\Inter\ShardingInitConfigInter;
use PhpShardingPdo\Test\Migrate\build\DatabaseCreate;
class ShardingInitConfig4 extends ShardingInitConfigInterTwo implementation styles coexist. An InlineShardingStrategyConfiguration with a modulo operator and a field name gives you a fixed rule, which is the common case, and the library ships with that percent based sharding rule built in. A configuration with an empty array plus an anonymous function gives you a custom rule, and the examples use a closure that inspects the condition values and returns an index. One example computes the target from a username with a checksum modulo the number of databases, another reads an id directly, and one returns a fixed zero, which pins a table to a single shard. Because the rules are code, they can be tested, and the trade-off is that a sharding rule becomes part of your application rather than a deployable configuration file.
A rule depends on the where conditions and on the inserted values
The routing inputs are stated explicitly in the documentation, and this is where the sharp edges are. Sharding rules depend on the input where conditions or on the data being inserted. That means a query without the right column in its where clause cannot be routed, and the rules are only as good as the conditions your application actually sends. The insert path is stricter still. If an insert matches multiple databases or multiple tables, the operation returns false, and the documentation asks you to confirm that the rule matching an insert resolves to exactly one database and one table. This is a fundamental property of sharding rather than a bug: an insert whose rule matches more than one shard cannot be placed. The practical consequence is that your write paths must carry the sharding key, and any code path that omits it will fail in a way that is easy to miss in development and painful in production.
Pagination across shards is slower, and the documentation says how to fix it
There is an honest performance note in the documentation about pagination. MySQL cannot use a scrolling cursor, so a paged query that fans out across databases and tables is described as comparatively slow, with the suggested remedy being to add a where condition that filters out unneeded result sets, such as an id lower bound or upper bound, so pagination stays efficient. The documentation contrasts this with the single database and single table case, where pagination speed is described as unchanged. So the cost is not in sharding itself but in the combination of sharding with a cursor style query, and the mitigation is to make the query selective enough that each shard can answer it cheaply. Teams that inherited a paginated list endpoint and then sharded the database behind it are the group most likely to hit this, and the fix is in the query rather than in the middleware.
Cross-database transactions can leave data inconsistent
The limitation the documentation states most plainly is about transactions. Inserting and updating in two or more databases in the same transaction carries a probability of failure because of the two phase commit, and a failed commit can leave the data inconsistent. The advice is to keep the data of a given dimension in one database, or to use flexible transactions and accept eventual consistency. This is the honest cost of sharding an existing schema, and it is why the library also offers an XA usage mode, which appears in the examples alongside basic queries, inserts, updates and deletes and join usage. Joins are the other structural constraint, since a join across shards cannot be executed by a single MySQL instance, so a join that spans a sharding boundary either has to be avoided or has to be assembled by the application. The middleware can route a statement to the right shard, but it cannot make the database do work that requires two shards to cooperate.
Coroutine mode has hard rules and a fatal error to recognise
The coroutine support is the part with the most operational sharp edges. Coroutines must be enabled in the main process, and the documentation is explicit that failing to do so causes a deadlock. It also warns that PDO long connections cannot be used inside coroutines, because under high concurrency you can hit an error like this.
PHP Fatal error: Uncaught Swoole\Error: Socket#30 has already been bound to another coroutine#2,
reading of the same socket in coroutine#4 at the same time is not allowedThat failure is a shared socket being read by two coroutines at once, which is exactly what happens when a persistent connection is reused concurrently. There is a related rule for the non-coroutine case, for long running processes such as Workerman, where the context has to be released at the end of a request or task because the context is a singleton holding PDO instances that time out and disconnect. After releasing it you must create a new Model instance, since the released context had its PDO instances cleared. The library also warns against Replace into with auto increment primary keys under high concurrency, where you can get a false return and a deadlock, and suggests a distributed primary key scheme such as a snowflake algorithm instead.
Installing it and running the integration tests
Installation is a single Composer requirement.
composer require lys/php-sharding-pdoTo run the test suite you need the source and the test database configuration, which lives in a.env file under the tests directory with a database section holding the host, username and password, and a shardingPdo section with a switch for recording SQL logs and the path for the log file. The documentation notes that turning SQL logging on affects performance. The clone and install steps are straightforward.
git clone https://github.com/1107012776/PHP-Sharding-PDO.git
cd PHP-Sharding-PDO
composer installThe suite is split by execution model, with a non coroutine integration test and a coroutine integration test, each filtered to a named test.
php vendor/bin/phpunit tests/IntegrationTest.php --filter testExecStartFor the coroutine path the second file is used instead.
php vendor/bin/phpunit tests/IntegrationCoroutineTest.php --filter testExecStartOn maintenance, the last push to the repository was on 2026-06-25, but the release tags are much older, with the most recent being v9.10.39 from 2023-11-09, preceded by v9.10.38 and v9.10.37 from July 2022. The documentation also advises using the current latest version.
Editorial conclusion
PHP-Sharding-PDO fits a team that already depends on PDO, needs to split MySQL tables across databases without rewriting its data access code, and can accept the rules being defined in PHP rather than in configuration files. It does not fit a project that needs distributed transactions to be safe by default, because the documentation itself warns that inserting and updating across two databases can fail to commit and leave data inconsistent, and it does not fit a team unwilling to follow the coroutine rules, since the process must enable Swoole coroutines or the library deadlocks. Before you adopt it, read the notes section rather than the examples, decide your sharding key on the where conditions and inserted values, and confirm your PHP version is at least 7.2 and your Swoole version at least 4.1.0 if you intend to run under coroutines.
Frequently asked questions
What is PHP-Sharding-PDO and what does it do?
It is a PHP and MySQL sharding library and middleware that depends on PDO and supports coroutines. It routes queries to the right database and table based on configurable sharding rules, and it offers basic query, insert, update, delete, join and XA usage.
How do I install PHP-Sharding-PDO?
The package is installed with Composer using composer require lys/php-sharding-pdo. The environment requirements are PHP 7.2 or newer, and Swoole 4.1.0 or newer when you run in a coroutine environment.
How are sharding rules defined in PHP-Sharding-PDO?
In a class that extends ShardingInitConfigInter, where each logical table gets a ShardingTableRuleConfig with a database sharding strategy and a table sharding strategy. Each strategy is an InlineShardingStrategyConfiguration, either with a built in percent rule over a named field or with an anonymous function that inspects the condition values and returns the target.
What happens if an insert matches multiple databases or tables?
The operation returns false. The documentation asks you to make sure the rule matching an insert resolves to exactly one database and one table, because a value that matches more than one shard cannot be placed.
Are cross-database transactions safe in PHP-Sharding-PDO?
Not by default. The documentation warns that inserting and updating across two or more databases in one transaction can fail to commit because of the two phase commit and leave the data inconsistent, and suggests keeping a dimension of data in one database or using flexible transactions for eventual consistency.
What are the coroutine requirements for PHP-Sharding-PDO?
Coroutines must be enabled in the main process or you will hit a deadlock, and PDO long connections cannot be used inside coroutines because concurrent reuse of the same socket raises a Swoole error about a socket being bound to another coroutine. In non coroutine long running processes, the context singleton must be released at the end of each request or task and a new Model created afterwards.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/1107012776-php-sharding-pdo)Was this useful?