数据库
云公会的所有资料都存在数据库里,设定文件只放规则。
| 类型 | 用在 | 说明 |
|---|---|---|
| SQLite(默认) | 单服 | 存在 plugins/CloudGuild/data.db(文件名在 database.file),使用 WAL 模式,单一连线 |
| MySQL / MariaDB | 多服共用 | database.type: mysql;InnoDB、utf8mb4,连接数 database.pool-size(默认 8),读已提交(READ COMMITTED)隔离级别 |
连接池 HikariCP 已内置在插件里;SQLite 与 MySQL 驱动使用 Paper 自带的。数据库连不上时,插件会在控制台显示原因并停用自己。设定见 config.yml。
表格前缀
所有表格名称前面都会加上 database.table-prefix(默认 cg_),只能用字母、数字与下划线,最多 32 个字。
- 多个子服要共用公会时,前缀必须一样。
- 同一个数据库里想放好几套互不相通的公会(例如两个独立的服务器群)时,才需要故意设不同的前缀。
表格一览
以默认前缀 cg_ 为例:
| 表格 | 内容 |
|---|---|
cg_meta | 内部资料:资料结构版本、每日结算的「今天已执行」记录 |
cg_guilds | 公会:名称、标签、介绍、图示、等级、资金、活跃、本月活跃、成员数、会长、加入方式、友伤、建立时间、击杀、死亡、胜场、败场 |
cg_members | 成员:所属公会、名称、职位、贡献、累积贡献、本周贡献、捐献、加入时间、最后上线、击杀、死亡(以玩家 UUID 为主键,一个玩家只能在一个公会) |
cg_players | 上线过的玩家:名称(用来寻找离线玩家)、离开公会的时间(重新加入冷却)、签到日期、连续天数、签到总次数 |
cg_applications | 入会申请 |
cg_invites | 邀请 |
cg_homes | 据点:名称、所在子服、世界、坐标 |
cg_notices | 公告 |
cg_notice_reads | 谁读过哪则公告 |
cg_relations | 同盟、敌对与同盟请求 |
cg_bank_log | 银行记录 |
cg_shop_usage | 每位玩家每个商品每个周期买了几次 |
cg_task_progress | 每个公会每个任务每一期的进度与是否完成 |
cg_task_contrib | 每位成员对每个任务每一期的出力 |
cg_buffs | 每个公会购买的增益等级 |
cg_vault | 仓库每一页的内容与锁 |
cg_wars | 公会战:双方、时间、比分、状态、胜方 |
cg_events | 跨服变动事件(给其他子服读取) |
cg_teleports | 跨服回据点时,等待目的子服处理的传送 |
表格在第一次启动时自动建立。
自动清理
每 10 分钟清理一次:
| 资料 | 保留 |
|---|---|
| 邀请 | 到期就删除(join.invite-expire) |
| 申请 | join.application-expire |
| 同盟请求 | relation.request-expire |
| 跨服事件 | 1 小时 |
| 跨服传送 | 2 分钟 |
| 任务进度与出力 | 21 天 |
银行记录在每日结算时裁到每个公会 bank.log-size 笔;公告超过 notice.max 时在发布新公告时删除最旧的。
安全性
- 每一笔会扣东西或有上限的操作,都是带条件的单条更新或事务(例如
UPDATE … SET funds = funds - ? WHERE id = ? AND funds >= ?),影响 0 行就是失败,不会先读再写。见 为什么用云公会。 - MySQL 在多个子服同时写入时回报死锁或等锁超时时,整个事务自动重做(最多 5 次)。
- 所有 SQL 都在插件自己的数据库线程池执行,不会卡主线程。
备份与搬服
- SQLite:整个
plugins/CloudGuild/资料夹。请在关服后复制;开服中复制时要连同data.db-wal、data.db-shm一起复制,否则可能缺少最近的资料。 - MySQL:备份数据库(例如
mysqldump cloudguild),以及每个子服的plugins/CloudGuild/(设定、菜单)。
SQLite ↔ MySQL 搬移
/cg admin migrate <sqlite|mysql> 把另一种数据库的全部 19 个表格复制到目前使用的数据库(在一个事务里完成,目标必须没有任何公会)。步骤见 从 SQLite 搬到 MySQL。