考虑这个选择语句:
SELECT *,
1 AS query_id
FROM players
WHERE username='foobar';
Run Code Online (Sandbox Code Playgroud)
它返回query_id带有值的列1以及玩家的其他列。
如何将一个至少让上面的SQL回报query_id的1,即使选择,反而找不到行那场比赛?
顺便说一句,它是 PostgreSQL 8.4。
首先,我不是 DBA,所以如果这个问题中的任何一个看起来“离题”,请原谅我。
我编写了一个点对点多人游戏(客户端),它连接到多个服务器之一进行匹配。
目前,只有一台服务器(一个 linode,我们称之为服务器 1)运行游戏的自定义匹配流程和 PostgreSQL 8.4(如有必要,我会将其升级到 9.1、9.2 或 9.3)。
匹配过程对所有 SQL 语句异步使用 libpq。语句不太复杂,因此负载平衡不是问题。
我计划添加更多 linode(称为服务器 2、3、4 等),以根据需要运行匹配过程和 PostreSQL。挑战在于我希望为所有客户提供高可用性。如果服务器 1 无法访问,则可以使用服务器 2 代替,访问所有相同的数据。
最初的计划是让所有服务器连接到服务器 1 的数据库并通过 libpq 异步发送 SQL 语句。问题在于,如果服务器 1 暂时离线或无法访问,那么其他所有服务器都将失败。
我能想象的“最简单”的解决方案是让每个服务器完全镜像数据库。如果服务器 1 关闭,客户端可以连接到服务器 2,后者读取和写入其自己的数据库,立即将任何更改复制到服务器 3 和 4,并在服务器 1 重新联机后复制。
以这种方式,每台服务器都将保存数据库的完整“镜像”副本。
在阅读了PostgreSQL 9.3 关于复制的文档的介绍部分后,似乎实现这个解决方案的方法是异步多主复制。(Bucardo 是这里唯一的选择吗?)
我担心异步复制是 SQL 插入。当新客户端第一次玩游戏时,会创建一个玩家数据库条目。如果服务器 2、3、4 在线而服务器 1 离线,如果 2 插入新的玩家行,1、3 或 4 会不会有任何问题?(想象一下 1 重新上线并立即尝试插入另一个玩家行。)
对于上述场景,异步多主节点是正确的方法吗?
或者,是否有我忽略的更简单或更容易的解决方案?也许不需要中间件,而只使用 PostgreSQL 9.3 的内置复制?