フロー節約アシスタント
このプロジェクトはMysqlのマスター・スレーブを使用しており、読み取りと書き込みを分離しているのですが、同期用のbinlogファイルを設定する際に間違ったファイル名を入力したため、マスターライブラリの更新内容がスレーブライブラリに同期されず、テーブル構造が崩れてしまっていました。期間中に変更されたため、インターフェイスがスレーブ ライブラリへのリクエストを開始すると、スレーブ ライブラリのテーブル構造がインスタンスに対応できないため、リクエストは失敗します (「フィールド リスト」の不明な列 'xxx')。以前のインターフェイスはすべて書き込み操作を伴い、すべてメイン ライブラリ上で動作するため、上記の問題は発生しませんでした。
解決策:マスター/スレーブ関係を設定し、マスター/スレーブ データベースを手動で同期します。
問題の分析と位置付け
問題のコードは次のとおりです。
@DS(DataSourceConstant.SLAVE)
@Override
public CouponEntity getById(Serializable id) {
ValueOperations<String,CouponEntity> couponOps = redisTemplate.opsForValue();
String key = COUPON_TEMPLATE_PREFIX+id;
CouponEntity couponEntity = couponOps.get(key);
if(couponEntity!=null){
return couponEntity;
}else{
// 将模版查询好放入到redis缓存中
System.out.println("查询");
CouponEntity entity = this.baseMapper.selectById(id);
System.out.println(entity);
couponOps.set(key,entity);
return entity;
}
}
関数の内容は一般的なクエリ文ですが、テストで問題が発生したため、データベースのフィールドを注意深くチェックした結果、問題は見つかりませんでした。以前は他のインターフェイスでも問題はありませんでした。つまり、couponDaoを直接呼び出す場合は問題ありませんが、このメソッド経由で呼び出すと問題が発生するため、テストコードは以下の通りです。
@RunWith(SpringRunner.class)
@SpringBootTest
public class CouponApplicationTests {
@Autowired
CouponService couponService;
@Autowired
CouponDao couponDao;
// 这个测试会报错Unknown column 'xxx' in 'field list'
@Test
public void TestEhCache() {
couponService.getById(9);
couponService.getById(9);
}
// 下面这个测试正常,没有报错
@Test
public void Testmysql() {
couponService.getBaseMapper().selectById(9);
couponDao.selectById(9);
}
}
インスタンスとデータベーステーブルのフィールド間のマッピングに問題はなく、要求されたSQL文も同じであるため、2つの方法のデータベース環境の違いによるエラーが考えられると分析できます。
質問コード内に @DS アノテーションがあり、データソースをスレーブライブラリに切り替える機能ですが、宣言されていない場合はデフォルトでメインライブラリになります。Navicat を使用して、スレーブ ライブラリとメイン ライブラリのテーブル構造が矛盾していることを確認します。
スレーブ ライブラリのステータスを表示するには show smile status; を使用
し、マスター ライブラリのステータスを表示するには show master status; を使用します
2 つの binglog (mysql-bin.xxxx) が矛盾していることがわかります。マスタ/スレーブ同期の設定に失敗します。
現時点で必要なのは、正しいマスター/スレーブ同期関係を設定し、マスター ライブラリとスレーブ ライブラリを手動で同期することだけです。
マスターデータベースとスレーブデータベースを手動で同期する
同期方法は、バックアップ SQL ファイルを再生することで同期を完了します
。1. 同期対象
テーブルのバックアップ SQL ファイルを取得し、メイン データベース マシン上で実行します。
# mysqldump -u<用户名> -p -h<主机地址> <数据库名> <表名> > <备份文件名>
mysqldump -uroot -p -hlocalhost greensource_sms sms_coupon_history > sms_coupon_history.bak.sql
2. バックアップをスレーブ データベース マシンに転送します。
3. スレーブ データベース mysql に接続し、source を使用して SQL を再生します。
source /sms_coupon_history.bak.sql
ファイルパスに注意する
4. 正しい主従関係を設定する
change master to master_host = '主库主机', master_user = '同步用户名', master_port=端口, master_password='密码', master_log_file = '主库的mysql-bin.xxxxxxxx', master_log_pos=主库的position;
start slave;
show slave status;
SQLが実行されるのを待つだけです。