💪 WordPress 使用 TiDB Cloud 替换 MySQL 💪

白嫖使我快乐。一直白嫖,一直快乐,😊。感谢 TiDB,感谢 TiDB Cloud,你们让我的博客内容更丰富多彩。

前言

我这个博客从 2011 年开始写,如今已经 12 年。最早,从 ZOL 离职后,我需要换个新平台写博客;另一方面,我也想学习 Linux、PHP、MySQL,这些原本不熟悉的技术,于是选择了 WordPress。这么多年来,服务器从共享主机搬迁到 VPS,又升级到云主机;PHP 从 5.5、5.6 升级到 7,又升级到 8;Apache 被换成 Nginx;唯独数据库没有变化,基本一套老框架沿用至今。

我前阵子发现:因为编码问题,无法在标题里或正文里插入表情符号。于是升级数据库也被提上日程。刚好我一直关注的 TiDB 开始提供云数据库服务,采用 Serverless 模式,Free Tier 有 5GB 可以用,足够我写博客。于是我就准备趁此机会切换到 TiDB Cloud 上。

注册 TiDB Cloud

打开 tidbcloud.com 注册即可。

TiDB Cloud 很大方,不需要绑卡,不需要繁琐的操作,直接第三方登录就可以使用。Serverless(Free Tier)只支持 AWS 机房,可选的位置也不多,因为我 ECS 买在美西,所以就把数据库也买在美西,这样速度应该会快一些。

每个账号可以创建若五个 Serverless 节点,有免费额度,超过限制用量则开始收费。只要稍稍点两下,就建好了,体验很流畅,这里不再赘述。接下来开始使用。

连接 TiDB Cloud

数据库准备就绪之后,我们可以进入数据库详情页。点击右上角的“Connect”按钮,即可打开连接信息窗口。

TiDB 贴心的准备了各种客户端、各种平台的连接方式,对于我这种数据库准小白来说非常有帮助。第一次使用,需要点击右下角的“Reset password”按钮生成数据库密码,生成后,这个按钮会变成复制密码。记得要妥善保存密码,因为我们不能再次查看或者获取。

这里发现一个设计缺陷:点击 Reset password 按钮没有确认过程,所以我的数据库密码直接就被改掉了……这种破坏性操作还是应该多一个确认比较好,回头反馈给 TiDB 的工作人员。

导入数据

TiDB Cloud 只支持导入 CSV 文件,比较难用。可能因为我数据库知识储备不足,我甚至想象不出 CSV 该怎么支持表结构😅。不过没关系,我有 JetBrains 全家桶,命令行操作也还凑合,所以直接从本地跑就行。

首先在服务器上执行 mysqldump -u USER -p --database BLOG_DB > backup.sql 把整个博客数据库包含数据结构都导出到 backup.sql 文件里。

打开 sql 文件,把数据库的编码全部改成 utf8mb4 或者 utf8mb4_unicode_ci,这样就可以支持表情符号咯 🎉🎉。

打开 DataGrip,按照上一节介绍建立数据库连接,右键,选择“SQL Scripts”,然后执行刚才的 SQL,等一会儿,数据即可完成导入。当然,实际过程肯定没有这么顺利,不过云数据库嘛,有问题就直接整个节点干掉再重建就好。不留脏数据。

WordPress 连接

TiDB Cloud 要求必须使用 TLS 安全连接,所以我们需要修改 wp-config.php

/** WordPress数据库的名称 */
define('DB_NAME', 'blog');

/** MySQL数据库用户名 */
define('DB_USER', '用户名');

/** MySQL数据库密码 */
define('DB_PASSWORD', '密码');

/** MySQL主机 */
define('DB_HOST', '主机域名:端口');

/** 使用 SSL 连接 */
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

因为我的服务器是 Ubuntu 22.04 系统,证书放在默认位置,可以自动加载。如果你使用其它系统,可能需要修改一下证书路径。

解决 SQL_CALC_FOUND_ROWS 导致翻页丢失的问题

完成上述操作,打开博客,500 😱。查看 error.log,原来是不支持 SQL_CALC_FOUND_ROWS 导致报错。我并不知道这个东西是干嘛用的,丢到 Google 里搜索,找到这个 issue,原来 WordPress 的 SQL 要使用这个函数,但是 TiDB 并不支持。

解决方案是在数据库里执行 SET GLOBAL tidb_enable_noop_functions=1。之后 WordPress 不会再报错,但是相应的,翻页功能也没有了,因为 WordPress 无法统计博文数量。

继续搜索。看起来 SQL_CALC_FOUND_ROWS 并不是什么好东西,不知道为什么 WordPress 至今都不愿意把它移除。还好,WP 留有开关,我们可以关闭这个函数的使用。我自己创建了一个 WP 小插件,用来给博客加广告、调整页面,所以我就在里面添加函数,关掉 SQL_CALC_FOUND_ROWS

if ( ! function_exists( 'wpartisan_set_no_found_rows' ) ) :
  function wpartisan_set_no_found_rows( \WP_Query $wp_query ) {
    $wp_query->set( 'no_found_rows', true );
  }
endif;
add_filter( 'pre_get_posts', 'wpartisan_set_no_found_rows', 10, 1 );

if ( ! function_exists( 'wpartisan_set_found_posts' ) ) :
  function wpartisan_set_found_posts( $clauses, \WP_Query $wp_query ) {
    // Don't proceed if it's a singular page.
    if ( $wp_query->is_singular()  ) {
      return $clauses;
    }

    global $wpdb;

    // Check if they're set.
    $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
    $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
    $distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';

    // Construct and run the query. Set the result as the 'found_posts'
    // param on the main query we want to run.
    $wp_query->found_posts = $wpdb->get_var( "SELECT $distinct COUNT(*) FROM {$wpdb->posts} $join WHERE 1=1 $where" );

    // Work out how many posts per page there should be.
    $posts_per_page = ( ! empty( $wp_query->query_vars['posts_per_page'] ) ? absint( $wp_query->query_vars['posts_per_page'] ) : absint( get_option( 'posts_per_page' ) ) );

    // Set the max_num_pages.
    $wp_query->max_num_pages = ceil( $wp_query->found_posts / $posts_per_page );

    // Return the $clauses so the main query can run.
    return $clauses;
  }
endif;
add_filter( 'posts_clauses', 'wpartisan_set_found_posts', 10, 2 );

调整完毕,翻页功能恢复正常。

使用体验小结

Serverless 讲究一个即用即起,平时是休眠状态,有人用才会启动。所以最好避免冷启动,否则第一个用的人要等很长时间,体验很差。作为博客,更简单的方式是配置 CDN,给首页外的页面添加长期缓存,就能改善大部分用户的体验。

实际上我目前使用了一个多月,并没有冷启动的感觉。我的博客日均几百的访问量,感觉相当可以。另外一个实例,作为 NoCoDB 的数据库,因为访问量很小,所以冷启动感觉很明显。

其它方面,速度和效率都不比本地数据库差,以后我再搞产品,应该都不会自己数据库了,嘿嘿嘿。


后记

我已经两次报名参加 TiDB Hackathon,第一次止步外围筛选第二次虽然进入决赛圈,但是因为对云数据库不了解,挑战开发 NoCoDB+TiDB Cloud 失败,铩羽而归。

但是借用群里同学的说法:人生没有白走的路,每一步,都算数。虽然 Hackathon 没能获得好成绩,但是我获得了更多关于 TiDB Cloud 的知识,于是这次可以顺利完成迁移。

目前博客网站使用体验良好,速度不比之前使用本地数据库慢。前两天,我发现 TiDB Cloud 开放了 Data Service,提供 HTTP Endpoint,这表示着他们向 DaaS(Database as a Service)更近一步,也意味着我们在 Edge Function 里使用 TiDB Cloud 成为可能。那么接下来,我打算好好利用一下这个薅羊毛机会,把几个 Side Project 的数据端放在 TiDB Cloud 上,跟 Supabase 比一比,看哪个更好用,更适合新项目、小公司从零到一。

到时候也会写成更多文章,或许做成视频,跟大家分享。

如果各位读者老爷对数据库、云开发、薅羊毛感兴趣,欢迎留言讨论,可提出问题,亦可指点一二,均非常欢迎。

如果您觉得文章内容对您有用,不妨支持我创作更多有价值的分享:


已发布

分类

来自

评论

欢迎吐槽,共同进步

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据