L'incohérence maître-esclave Mysql provoque la colonne inconnue « xxx » dans la « liste de champs »

Assistant d'économie de débit

Le projet utilise Mysql maître-esclave et sépare la lecture et l'écriture, mais a entré un nom de fichier incorrect lors de la définition du fichier binlog de synchronisation, ce qui a entraîné la non-synchronisation du contenu de mise à jour de la bibliothèque maître avec la bibliothèque esclave et parce que la structure de la table était modifié pendant la période, donc lorsque l'interface lance une requête vers la bibliothèque esclave, la requête échoue (colonne inconnue 'xxx' dans 'liste de champs') car la structure de la table de la bibliothèque esclave ne peut pas correspondre à l'instance. Les interfaces précédentes impliquaient toutes des opérations d’écriture et fonctionnaient toutes sur la bibliothèque principale, de sorte que les problèmes ci-dessus ne se produisaient pas.
Solution : configurez la relation maître-esclave et synchronisez manuellement la base de données maître-esclave.

Analyse du problème et positionnement

Le code du problème est le suivant :

    @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;
        }
    }

Le contenu de la fonction est une instruction de requête générale, mais il y a eu un problème dans le test. Après avoir soigneusement vérifié les champs de la base de données, aucun problème n'a été trouvé et il n'y avait aucun problème avec d'autres interfaces auparavant. C'est-à-dire qu'il n'y aura aucun problème si vous appelez directement couponDao, mais il y aura des problèmes si vous l'appelez via cette méthode. Le code de test est le suivant :

@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);
    }
}

On peut analyser qu'il n'y a aucun problème dans le mappage entre l'instance et les champs de la table de base de données, et que les instructions SQL demandées sont les mêmes, donc le problème possible est l'erreur causée par les différents environnements de base de données des deux méthodes.

Il y a l'annotation @DS dans le code de la question, sa fonction est de basculer la source de données vers la bibliothèque esclave. Si elle n'est pas déclarée, elle est par défaut sur la bibliothèque principale. Utilisez Navicat pour vérifier et constater que la structure des tables de la bibliothèque esclave et de la bibliothèque principale sont incohérentes.
Utilisez show slave status ; pour afficher l’état de la bibliothèque esclave.
Utilisez show master status ; pour afficher l’état de la bibliothèque principale.
Il s’avère que le binglog (mysql-bin.xxxx) des deux est incohérent, c’est-à-dire : le paramètre de synchronisation maître-esclave échoue.
À ce stade, il vous suffit de définir la relation de synchronisation maître-esclave correcte et de synchroniser manuellement les bibliothèques maître et esclave.

Synchronisez manuellement les bibliothèques maître et esclave

La méthode de synchronisation consiste à terminer la synchronisation en relisant le fichier SQL de sauvegarde.
Elle est divisée en les étapes suivantes :
1. Obtenez le fichier SQL de sauvegarde de la table à synchroniser et exécutez-le sur la machine principale de la base de données.

# mysqldump -u<用户名> -p -h<主机地址> <数据库名> <表名> > <备份文件名>
mysqldump -uroot -p -hlocalhost greensource_sms sms_coupon_history > sms_coupon_history.bak.sql

2. Transférez la sauvegarde sur la machine de base de données esclave
3. Connectez-vous à la base de données esclave mysql et utilisez la source pour rejouer le SQL

source /sms_coupon_history.bak.sql

Faites attention au chemin du fichier
4. Définissez la bonne relation maître-esclave

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;

Attendez simplement la fin de l’exécution de SQL.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45654405/article/details/127351433
conseillé
Classement