Rumah pangkalan data tutorial mysql Mongdb的upsert出现E11000 duplicate key errors的错误分析

Mongdb的upsert出现E11000 duplicate key errors的错误分析

Jun 07, 2016 pm 02:53 PM
Muncul

Mongdb的upsert出现E11000 duplicate key errors的错误分析 昨日上线的系统,今天查日志时发现有不少E11000 duplicate key errors的报错日志,当时 十分费解,因为用的upsert,这个是原子操作,避免了线程并发带来的问题,但为什么会报 重复主键的错误呢? w


Mongdb的upsert出现E11000 duplicate key errors的错误分析

 

昨日上线的系统,今天查日志时发现有不少E11000 duplicate key errors的报错日志,当时
十分费解,因为用的upsert,这个是原子操作,避免了线程并发带来的问题,但为什么会报
重复主键的错误呢?

www.2cto.com  

Java代码  

update( DBObject q , DBObject o , boolean upsert , boolean multi )  

第一个参数是查询条件,第一个参数是要做的操作。

 

我的处理逻辑是这样的,集合中有3列联合唯一索引,此外还有6列属性值,4列要增加的列。

 

我的查询条件q是这么写的

Java代码  

QueryBuilder.start("mb").is(bsc.getMb()).and("sb").is(bsc.getSb()).and("fd").is(bsc.getFd())  

                    .and("mft").is(bsc.getMft()).and("mst").is(bsc.getMst()).and("mtt").is(bsc.getMtt())  

                    .and("sft").is(bsc.getSft()).and("sst").is(bsc.getSst()).and("stt").is(bsc.getStt())  

                    .get()  

 mb,sb,fd是联合唯一索引。

要做的操作是

Java代码  

QueryBuilder.start("$inc").is(QueryBuilder.start("mc0").is(bsc.getMc0()).and("mc1").is
(bsc.getMc1())  

                    .and("sc0").is(bsc.getSc0()).and("sc1").is(bsc.getSc1()).get())  

                    .get();  

在测试时是一点问题都没有的

但为什么会有duplicate key errors呢?

upsert的原理是先根据q去查询,若没有结果,则先insert,若有结果则根据o进行update

所以唯一可能的问题是那6个属性列,因为它们不是唯一索引列,但仍然出现在查询条件中,
这样就会出现索引列的值一样,但是属性列的值不一样,这样Mongodb进行insert,由于库中
已经有了和当前值唯一索引相同的记录,故出现duplicate key errors。属性列的值是与索引列的值
相关联的,但可能在计算的时候出错,导致属性列的值得到错误的结果。

   www.2cto.com  

同时,在Mongodb的官网jira中也有这个问题的讨论https://jira.mongodb.org/browse/SERVER-5928

Java代码  

// Insert test document  

> db.test.insert({_id:1, version:2, data:3})  

// Get current document  

> var doc = db.test.findOne({_id:1});  

> printjson(doc);  

{  

        "_id" : 1,  

        "version" : 2,  

        "data" : 3  

}  

// Perform some updates on doc.data  

...  

// Update  

> db.test.update({_id:1, version:doc.version},{$set:{data:doc.data}, $inc:{version:1}}, true);
db.getLastError();  

// Update succeeded  

null  

// Try once more  

> db.test.update({_id:1, version:doc.version},{$set:{data:doc.data}, $inc:{version:1}}, true);  

// Failed with "non-unique key" since "version" field changed  

E11000 duplicate key error index: d2_feed0.feed.$_id_  dup key: { : 1 }  

 注意倒数第二行的

Java代码  

Failed with "non-unique key" since "version" field changed  

 和我得出的结论是一致的。

 以后在使用upsert时,在查询条件中尽量只有唯一索引的列。

修改之后的代码

  www.2cto.com  

Java代码  

DBObject q = QueryBuilder.start("mb").is(bsc.getMb()).and("sb").is(bsc.getSb()).and("fd").
is(bsc.getFd()).get();  

            DBObject o = QueryBuilder.start("$set")  

                    .is(QueryBuilder.start("mft").is(bsc.getMft()).and("mst").is(bsc.getMst()).and("mtt").
is(bsc.getMtt())  

                            .and("sft").is(bsc.getSft()).and("sst").is(bsc.getSst()).and("stt").is(bsc.getStt())  

                            .get())  

                    .and("$inc").is(QueryBuilder.start("mc0").is(bsc.getMc0()).and("mc1").is(bsc.getMc1())  

                            .and("sc0").is(bsc.getSc0()).and("sc1").is(bsc.getSc1()).get())  

                    .get();  

 使用set来解决可能出现的不一致问题。

 

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Kurangkan penggunaan memori MySQL di Docker Kurangkan penggunaan memori MySQL di Docker Mar 04, 2025 pm 03:52 PM

Artikel ini meneroka mengoptimumkan penggunaan memori MySQL di Docker. Ia membincangkan teknik pemantauan (statistik Docker, skema prestasi, alat luaran) dan strategi konfigurasi. Ini termasuk had memori docker, swapping, dan cgroups, bersama -sama

Cara menyelesaikan masalah MySQL tidak dapat membuka perpustakaan bersama Cara menyelesaikan masalah MySQL tidak dapat membuka perpustakaan bersama Mar 04, 2025 pm 04:01 PM

Artikel ini menangani ralat "tidak dapat membuka perpustakaan kongsi" MySQL. Isu ini berpunca daripada ketidakupayaan MySQL untuk mencari perpustakaan bersama yang diperlukan (.so/.dll fail). Penyelesaian melibatkan mengesahkan pemasangan perpustakaan melalui pakej sistem m

Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Mar 19, 2025 pm 03:51 PM

Artikel ini membincangkan menggunakan pernyataan jadual Alter MySQL untuk mengubah suai jadual, termasuk menambah/menjatuhkan lajur, menamakan semula jadual/lajur, dan menukar jenis data lajur.

Jalankan MySQL di Linux (dengan/tanpa bekas podman dengan phpmyadmin) Jalankan MySQL di Linux (dengan/tanpa bekas podman dengan phpmyadmin) Mar 04, 2025 pm 03:54 PM

Artikel ini membandingkan memasang MySQL pada Linux secara langsung berbanding menggunakan bekas podman, dengan/tanpa phpmyadmin. Ia memperincikan langkah pemasangan untuk setiap kaedah, menekankan kelebihan Podman secara berasingan, mudah alih, dan kebolehulangan, tetapi juga

Apa itu SQLite? Gambaran Keseluruhan Komprehensif Apa itu SQLite? Gambaran Keseluruhan Komprehensif Mar 04, 2025 pm 03:55 PM

Artikel ini memberikan gambaran menyeluruh tentang SQLite, pangkalan data relasi tanpa server tanpa mandiri. Ia memperincikan kelebihan SQLITE (kesederhanaan, mudah alih, kemudahan penggunaan) dan kekurangan (batasan konkurensi, cabaran skalabiliti). C

Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Mar 18, 2025 pm 12:01 PM

Artikel membincangkan mengkonfigurasi penyulitan SSL/TLS untuk MySQL, termasuk penjanaan sijil dan pengesahan. Isu utama menggunakan implikasi keselamatan sijil yang ditandatangani sendiri. [Kira-kira aksara: 159]

Menjalankan Pelbagai Versi MySQL di MacOS: Panduan Langkah demi Langkah Menjalankan Pelbagai Versi MySQL di MacOS: Panduan Langkah demi Langkah Mar 04, 2025 pm 03:49 PM

Panduan ini menunjukkan pemasangan dan menguruskan pelbagai versi MySQL pada macOS menggunakan homebrew. Ia menekankan menggunakan homebrew untuk mengasingkan pemasangan, mencegah konflik. Pemasangan Butiran Artikel, Permulaan/Perhentian Perkhidmatan, dan PRA Terbaik

Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Mar 21, 2025 pm 06:28 PM

Artikel membincangkan alat MySQL GUI yang popular seperti MySQL Workbench dan PHPMyAdmin, membandingkan ciri dan kesesuaian mereka untuk pemula dan pengguna maju. [159 aksara]

See all articles