قد تفشل عمليات الإدراج أحيانًا بسبب أخطاء مثل انتهاء المهلة. وعند فشلها، قد تكون البيانات قد أُدرجت بنجاح أو لا. يوضح هذا الدليل كيفية عمل إزالة التكرار عند إعادة محاولة الإدراج، بحيث لا تُدرج البيانات نفسها أكثر من مرة.
عند إعادة محاولة الإدراج، يحاول ClickHouse التحقق مما إذا كانت البيانات قد أُدرجت بنجاح بالفعل. وإذا وُسِمت البيانات المُدرجة على أنها مكررة، فلن يُدرجها ClickHouse في الجدول الوجهة. ومع ذلك، سيظل المستخدم يتلقى حالة نجاح للعملية كما لو كانت البيانات قد أُدرجت بشكل طبيعي.
تشمل إزالة التكرار عمليات الإدراج المتزامنة، وعمليات الإدراج غير المتزامنة، واستعلامات INSERT ... SELECT. يتحكم إعداد واحد، وهو deduplicate_insert، في عمليات الإدراج المتزامنة وغير المتزامنة. تتطلب INSERT ... SELECT عناية إضافية ولها إعداد خاص بها. راجع الإعدادات التي تتحكم في إزالة تكرار عمليات الإدراج.
القيود
حالة الإدراج غير المؤكدة
يجب على المستخدم إعادة محاولة عملية الإدراج حتى تنجح. وإذا فشلت جميع المحاولات، يصبح من المستحيل تحديد ما إذا كانت البيانات قد أُدرجت أم لا. وعندما تكون العروض المادية معنية، لا يكون واضحًا أيضًا في أي الجداول ربما ظهرت البيانات. وقد تكون العروض المادية غير متزامنة مع الجدول المصدر.
حد نافذة إزالة التكرار
إذا جرت أكثر من *_deduplication_window عملية إدراج أخرى أثناء تسلسل إعادة المحاولة، فقد لا تعمل إزالة التكرار كما هو مقصود. في هذه الحالة، قد تُدرَج البيانات نفسها عدة مرات.
الإعدادات التي تتحكم في إزالة التكرار
لا يزيل ClickHouse تكرار عملية إدراج إلا عند استيفاء الشرطين التاليين:
- أن يحتفظ الجدول الوجهة بسجل لإزالة التكرار. هذا إعداد على مستوى الجدول.
- أن تكون إزالة التكرار مفعّلة للاستعلام. هذا إعداد على مستوى الاستعلام.
إعدادات على مستوى الجدول
لا تدعم إزالة التكرار عند الإدراج سوى محرّكات *MergeTree.
بالنسبة إلى محرّكات *ReplicatedMergeTree، يكون سجل إزالة التكرار مفعّلًا افتراضيًا، ويتحكم فيه الإعدادان replicated_deduplication_window وreplicated_deduplication_window_seconds. أما في محرّكات *MergeTree غير المكرّرة، فيتحكم في السجل الإعداد non_replicated_deduplication_window، الذي تكون قيمته 0 افتراضيًا. لذلك، لا يزيل جدول MergeTree العادي أي تكرار حتى تضبط تلك النافذة على قيمة موجبة.
تحدّد الإعدادات أعلاه معلمات سجل إزالة التكرار للجدول. ويخزّن سجل إزالة التكرار عددًا محدودًا من block_ids`، وهي التي تحدد آلية عمل إزالة التكرار (انظر أدناه).
إعدادات على مستوى الاستعلام
| الإعداد | ينطبق على | القيمة الافتراضية | الغرض |
|---|---|---|---|
deduplicate_insert |
كل INSERT، سواء كان متزامنًا أو غير متزامن |
enable |
المفتاح الرئيسي لإزالة تكرار عمليات الإدراج |
deduplicate_insert_select |
INSERT ... SELECT |
enable_when_possible |
يحدد الإجراء المتخذ عندما تكون نتيجة SELECT غير قابلة لإعادة الإنتاج |
insert_deduplication_token |
كل INSERT |
'' |
يحدد عملية الإدراج باستخدام سلسلة يوفّرها المستخدم بدلًا من البيانات |
deduplicate_blocks_in_dependent_materialized_views |
الجداول التابعة للعروض المادية | 1 |
يوسّع إزالة التكرار لتشمل وجهات العروض المادية التابعة |
يقبل deduplicate_insert ثلاث قيم:
enable— تُفعّل إزالة التكرار لاستعلامINSERT.disable— تُعطّل إزالة التكرار لاستعلامINSERT.backward_compatible_choice— يُفوَّض القرار إلى الإعدادات القديمةinsert_deduplicate(عمليات الإدراج المتزامنة) وasync_insert_deduplicate(عمليات الإدراج غير المتزامنة).
لاحظ أن الاستعلام الذي يعمل مع deduplicate_insert = disable لا يكتب أي قيم block_id لكتله. ولا يمكن إزالة تكرار هذه البيانات لاحقًا، حتى إذا أعدت محاولة الإدراج باستخدام deduplicate_insert = enable. وينطبق الأمر نفسه عندما لا يحتفظ جدول الوجهة بسجل إزالة التكرار: فلا يُسجَّل شيء، وبالتالي لا يمكن مطابقة أي شيء عند إعادة المحاولة.
الأسبقية
- بالنسبة إلى استعلام
INSERT ... SELECT، تكون الأولوية لـdeduplicate_insert_select. راجع إزالة التكرار لـ INSERT … SELECT. - بالنسبة إلى جميع عمليات
INSERTالأخرى، تكون الأولوية لـdeduplicate_insert. - لا تُقرأ
insert_deduplicateوasync_insert_deduplicateإلا عندما تكون قيمةdeduplicate_insertهيbackward_compatible_choice.
الإعدادات الموروثة والمتقادمة
| الإعداد | الحالة | استخدم بدلًا منه |
|---|---|---|
insert_deduplicate |
موروث. لا يُقرأ إلا عندما تكون قيمة deduplicate_insert = backward_compatible_choice |
deduplicate_insert |
async_insert_deduplicate |
موروث. لا يُقرأ إلا عندما تكون قيمة deduplicate_insert = backward_compatible_choice |
deduplicate_insert |
insert_select_deduplicate |
متقادم. ليس له أي تأثير | deduplicate_insert_select |
update_insert_deduplication_token_in_dependent_materialized_views |
متقادم. ليس له أي تأثير | — |
غيّر الإصدار 26.2 أيضًا القيم الافتراضية لـ async_insert وdeduplicate_blocks_in_dependent_materialized_views إلى مفعّلة. يتحكم إعداد compatibility في الإعدادات الثلاثة جميعها. إذا ضبطت compatibility على إصدار أقدم من 26.2، فستحتفظ هذه الإعدادات بقيمها الافتراضية القديمة: تصبح قيمة deduplicate_insert هي backward_compatible_choice، ما يُحيل القرار إلى insert_deduplicate وasync_insert_deduplicate. ويُطبَّق دائمًا أي إعداد تعيّنه صراحةً، ولا يتأثر مطلقًا بـ compatibility.
كيف تعمل إزالة التكرار عند الإدراج
عند إدراج البيانات في ClickHouse، تُقسَّم البيانات إلى كتل استنادًا إلى عدد الصفوف والبايتات.
بالنسبة إلى الجداول التي تستخدم محركات *MergeTree، يُخصَّص لكل كتلة block_id فريد، وهو hash لبيانات تلك الكتلة. ويُستخدم block_id هذا كمفتاح فريد لعملية الإدراج. وإذا عُثر على block_id نفسه في سجل إزالة التكرار، تُعتبر الكتلة مكررة ولا تُدرج في الجدول.
يعمل هذا النهج جيدًا عندما تحتوي عمليات الإدراج على بيانات مختلفة. ولكن إذا أُدرجت البيانات نفسها عدة مرات عن قصد، فستحتاج إلى استخدام الإعداد insert_deduplication_token للتحكم في عملية إزالة التكرار. يتيح لك هذا الإعداد تحديد رمز مميز فريد لكل عملية إدراج، ويستخدم ClickHouse هذا الرمز لتحديد ما إذا كانت البيانات مكررة. يتمتع insert_deduplication_token بأولوية أعلى: لا يستخدم ClickHouse قيمة hash للبيانات عند توفير الرمز.
بالنسبة إلى استعلامات INSERT ... VALUES، يكون تقسيم البيانات المُدرجة إلى كتل حتميًا ويتحدد بواسطة الإعدادات. لذلك، ينبغي إعادة محاولة الإدراج باستخدام قيم الإعدادات نفسها التي استُخدمت في العملية الأولى.
إزالة التكرار في INSERT ... SELECT
بالنسبة إلى استعلامات INSERT ... SELECT، يجب أن يُرجع جزء SELECT البيانات نفسها وبالترتيب نفسه في كل محاولة. وإلا فستختلف الكتل وblock_ids، ولن يُتعرّف على إعادة المحاولة باعتبارها مكررة.
لا يستطيع ClickHouse التحقق من عدم تغيّر البيانات المصدر، لكنه يستطيع التحقق مما إذا كان الاستعلام نفسه ينتج نتيجة قابلة لإعادة الإنتاج. يُعامل SELECT على أنه مستقر عند استيفاء الشرطين التاليين:
- أن يتضمن الاستعلام عبارة
ORDER BY ALL. لا يُتعرّف إلا على الصيغة الحرفيةORDER BY ALL. أماORDER BY <expressions>العادي فلا يُتعرّف عليه، ولا يكونUNIONمن عمليتيSELECTأو أكثر مستقرًا أبدًا. - أن ينتهي مسار القراءة بتدفق واحد.
يُعدّ insert_deduplication_token غير الفارغ بديلًا مكافئًا للاستقرار، لأن الرمز، وليس البيانات، هو ما يعرّف عملية الإدراج في هذه الحالة.
يحدد الإعداد deduplicate_insert_select الإجراء المتبع:
| القيمة | السلوك |
|---|---|
enable_when_possible (افتراضي) |
أزل التكرار عندما يكون SELECT مستقرًا أو عند تعيين رمز. وإلا، فتجاوز إزالة التكرار واكتب رسالة في سجل الخادم. |
force_enable |
أزل التكرار دائمًا. إذا لم يكن SELECT مستقرًا ولم يُعيَّن رمز، فأطلق الاستثناء DEDUPLICATION_IS_NOT_POSSIBLE. |
enable_even_for_bad_queries |
أزل التكرار بغض النظر عن الاستقرار. يُحتفَظ به للتوافق مع الإصدارات السابقة. مع SELECT غير مستقر، لا يُتعرّف عادةً على إعادة المحاولة باعتبارها مكررة، لذا يُفضّل استخدام قيمة أخرى. |
disable |
لا تزل تكرار INSERT ... SELECT أبدًا. |
يحترم كل من enable_when_possible وenable_even_for_bad_queries أيضًا deduplicate_insert: إذا كانت قيمته disable، فلن يُزال تكرار الاستعلام. يتجاوز force_enable قيمة deduplicate_insert.
ضع في اعتبارك أنه قد يُحدَّث الجدول المحدد بين عمليات إعادة المحاولة. عندها يتصرف المساران بصورة متعاكسة:
- بدون
insert_deduplication_token، تُحسبblock_ids من البيانات. تؤدي النتيجة المتغيرة إلىblock_ids مختلفة، فلا تحدث إزالة التكرار، وتُدرج إعادة المحاولة البيانات الجديدة فوق أي بيانات كتبتها المحاولة الأولى بالفعل. - مع
insert_deduplication_token، يعرّف الرمز وحده عملية الإدراج. يُتعرّف على إعادة المحاولة باعتبارها مكررة وتُسقط، حتى لو كانت ستدرج بيانات مختلفة.
اختر المسار الذي يتوافق مع المعنى الذي تريده لإعادة المحاولة. كذلك، عند إدراج كميات كبيرة من البيانات، قد يتجاوز عدد الكتل نافذة سجل إزالة التكرار، وعندها لن يعرف ClickHouse أن عليه إزالة تكرار الكتل.
إزالة التكرار لعمليات الإدراج غير المتزامنة
تُزال تكرارات عمليات الإدراج غير المتزامنة (async_insert، وهي مفعّلة افتراضيًا منذ الإصدار 26.2) عند إعادة المحاولة بالطريقة نفسها المتبعة لعمليات الإدراج المتزامنة. ويتحكم deduplicate_insert في كليهما، لذا لا حاجة إلى مفتاح منفصل.
يشترك نوعا الإدراج أيضًا في سجل واحد لإزالة التكرار، ويحسبان block_ids بالطريقة نفسها. لذلك، يمكنك تبديل العميل بين عمليات الإدراج المتزامنة وغير المتزامنة دون التأثير في إزالة التكرار، وتبقى إعادة المحاولة المُرسلة في أحد الوضعين معروفة كتكرار لمحاولة أُرسلت في الوضع الآخر. كما يبقى نقل حمل عمل من عمليات الإدراج المتزامنة إلى غير المتزامنة آمنًا في جدول يعتمد على إزالة التكرار.
دقة إزالة التكرار
يجمع الخادم عدة عمليات إدراج غير متزامنة في دفعة واحدة ويكتب هذه الدفعة في جزء واحد أو أكثر، بواقع جزء واحد على الأقل لكل قيمة مميزة لمفتاح التقسيم. تعمل إزالة التكرار على مستوى استعلام المستخدم، وليس على مستوى الدفعة:
- يضيف كل استعلام في قائمة الانتظار رمزاً واحداً لإزالة التكرار إلى الدفعة.
- يكون الرمز إما قيمة
insert_deduplication_tokenإذا وفّرها الاستعلام، أو hash للصفوف التي أضافها هذا الاستعلام. - لا يؤثر التجميع في دفعات في الرموز، كما لا يؤثر
insert_deduplication_tokenفي كيفية تجميع الاستعلامات ضمن دفعات.
ينتج عن ذلك نتيجتان:
- إذا كان أحد الاستعلامات في دفعة مكرراً، فإن ClickHouse يزيل صفوف ذلك الاستعلام فقط. وتُدرج بقية الدفعة بشكل طبيعي. ولا يُتخطى الجزء بالكامل إلا إذا أُزيلت جميع صفوفه.
- إذا حمل استعلامان في الدفعة نفسها الرمز ذاته، يُسقط الاستعلام الثاني قبل كتابة الجزء. ينطبق ذلك على كل تقسيم على حدة: فإذا كتب الاستعلامان صفوفاً في تقسيمات مختلفة، يُحتفظ بكليهما.
تحصي الأحداث DuplicatedAsyncInserts وSelfDuplicatedAsyncInserts في system.events هاتين الحالتين.
عمليات الإدراج غير المتزامنة والعروض المادية
تعمل إزالة التكرار في عمليات الإدراج غير المتزامنة بالتزامن مع العروض المادية التابعة. القاعدة بسيطة: كتلة واحدة تدخل، وكتلة واحدة تخرج. إذا حوّل الاستعلام الداخلي لعرض كتلة إدخال واحدة إلى كتلة إخراج واحدة، تعمل إزالة التكرار. أما إذا أصدر العرض كتلة ثانية، فيُطلق ClickHouse استثناء NOT_IMPLEMENTED.
يصدر العرض كتلة ثانية عندما لا يعود الإخراج ضمن كتلة واحدة. يحدد max_block_size عدد الصفوف التي يمكن أن تتسع لها الكتلة. لا تضيف تحويلات الأعمدة أو التصفية أو التجميع صفوفًا، لذا تبقى دائمًا ضمن كتلة واحدة. يمكن أن يضيف JOIN صفوفًا. ويعمل ما دامت النتيجة لا تتجاوز max_block_size، ويفشل عند تجاوزها.
للإدراج عبر عرض يصدر أكثر من كتلة واحدة، عيّن deduplicate_blocks_in_dependent_materialized_views = 0 أو استخدم عمليات الإدراج المتزامنة.
إزالة التكرار عند الإدراج مع العروض المادية
عندما يحتوي جدول على عرض مادي واحد أو أكثر، تُدرَج البيانات أيضًا في وجهة تلك العروض مع التحويلات المحددة. كما يُزال تكرار البيانات المُحوَّلة عند إعادة المحاولة أيضًا. ويُجري ClickHouse إزالة التكرار للعروض المادية بالطريقة نفسها التي يُجري بها إزالة التكرار للبيانات المُدرجة في الجدول الهدف.
يمكنك التحكم في هذه العملية باستخدام الإعدادات التالية للجدول المصدر:
replicated_deduplication_windowreplicated_deduplication_window_secondsnon_replicated_deduplication_window
تخضع إزالة التكرار في الجداول التابعة للعروض المادية أيضًا لإعداد ملف تعريف المستخدم deduplicate_blocks_in_dependent_materialized_views، وهو مُمكّن افتراضيًا منذ الإصدار 26.2. يجب أن يسمح كلا الإعدادين بذلك: يزيل deduplicate_insert تكرار البيانات المُدرجة في الجدول المصدر، ويزيل deduplicate_blocks_in_dependent_materialized_views أيضًا تكرار البيانات في الجداول التابعة. مكّن الإعدادين كليهما إذا كنت تريد إزالة التكرار الكاملة.
عند إدراج كتل في الجداول التابعة للعروض المادية، يحسب ClickHouse قيمة block_id عبر إجراء تجزئة لسلسلة تجمع بين قيم block_id من الجدول المصدر ومعرّفات إضافية. ويضمن ذلك إزالة تكرار دقيقة داخل العروض المادية، بحيث يمكن تمييز البيانات استنادًا إلى عملية إدراجها الأصلية، بغض النظر عن أي تحويلات طُبّقت عليها قبل وصولها إلى جدول الوجهة التابع للعرض المادي.
أمثلة
الكتل المتطابقة بعد التحويلات في العرض المادي
الكتل المتطابقة التي جرى إنشاؤها أثناء التحويل داخل العرض المادي لا تُزال تكراراتها، لأنها تستند إلى بيانات مُدرجة مختلفة.
إليك مثالًا:
CREATE TABLE dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
CREATE MATERIALIZED VIEW mv_dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000
AS SELECT
0 AS key,
value AS value
FROM dst;SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;تتيح لنا الإعدادات أعلاه إجراء استعلام على جدول يحتوي على سلسلة من الكتل، لا يحتوي كلٌّ منها إلا على صف واحد. هذه الكتل الصغيرة لا تُدمَج، وتبقى كما هي حتى تُدرَج في جدول.
نحدد إزالة التكرار في العرض المادي صراحةً، رغم أنها مفعّلة افتراضيًا:
SET deduplicate_blocks_in_dependent_materialized_views=1;INSERT INTO dst SELECT
number + 1 AS key,
IF(key = 0, 'A', 'B') AS value
FROM numbers(2);
SELECT
*,
_part
FROM dst
ORDER BY all;┌─key─┬─value─┬─_part─────┐
│ 1 │ B │ all_0_0_0 │
│ 2 │ B │ all_1_1_0 │
└─────┴───────┴───────────┘نرى هنا أنه تم إدراج جزأين في الجدول dst. كتلتان من SELECT – وجزآن عند الإدراج. تحتوي الأجزاء على بيانات مختلفة.
SELECT
*,
_part
FROM mv_dst
ORDER BY all;┌─key─┬─value─┬─_part─────┐
│ 0 │ B │ all_0_0_0 │
│ 0 │ B │ all_1_1_0 │
└─────┴───────┴───────────┘هنا نرى أنه تم إدراج جزأين في جدول mv_dst. يحتوي هذان الجزآن على البيانات نفسها، لكن لم تُزل التكرارات بينهما.
INSERT INTO dst SELECT
number + 1 AS key,
IF(key = 0, 'A', 'B') AS value
FROM numbers(2);
SELECT
*,
_part
FROM dst
ORDER BY all;┌─key─┬─value─┬─_part─────┐
│ 1 │ B │ all_0_0_0 │
│ 2 │ B │ all_1_1_0 │
└─────┴───────┴───────────┘SELECT
*,
_part
FROM mv_dst
ORDER by all;┌─key─┬─value─┬─_part─────┐
│ 0 │ B │ all_0_0_0 │
│ 0 │ B │ all_1_1_0 │
└─────┴───────┴───────────┘نرى هنا أنه عند إعادة محاولة عمليات الإدراج، تُزال جميع البيانات المكررة. وتعمل آلية إزالة التكرار مع الجدولين dst وmv_dst.
الكتل المتطابقة عند الإدراج
CREATE TABLE dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;الإدراج:
INSERT INTO dst SELECT
0 AS key,
'A' AS value
FROM numbers(2);
SELECT
'from dst',
*,
_part
FROM dst
ORDER BY all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 0 │ A │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘باستخدام الإعدادات أعلاه، تنتج كتلتان من select– ونتيجةً لذلك، ينبغي أن تكون هناك كتلتان لإدخالهما في الجدول dst. ومع ذلك، نرى أنه لم تُدرج سوى كتلة واحدة في الجدول dst. حدث ذلك لأن الكتلة الثانية أُزيل تكرارها. فهي تحتوي على البيانات نفسها وعلى مفتاح إزالة التكرار block_id، الذي يُحتسب على شكل hash من البيانات المُدرجة. هذا السلوك ليس ما كان متوقعًا. مثل هذه الحالات نادرة الحدوث، لكنها ممكنة نظريًا. وللتعامل مع مثل هذه الحالات على نحو صحيح، يجب على المستخدم توفير insert_deduplication_token. لنُصلِح ذلك بالأمثلة التالية:
الكتل المتطابقة عند الإدراج باستخدام insert_deduplication_token
CREATE TABLE dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;الإدراج:
INSERT INTO dst SELECT
0 AS key,
'A' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';
SELECT
'from dst',
*,
_part
FROM dst
ORDER BY all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 0 │ A │ all_2_2_0 │
│ from dst │ 0 │ A │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘أُدرجت كتلتان متطابقتان كما هو متوقع.
SELECT 'second attempt';
INSERT INTO dst SELECT
0 AS key,
'A' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';
SELECT
'from dst',
*,
_part
FROM dst
ORDER BY all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 0 │ A │ all_2_2_0 │
│ from dst │ 0 │ A │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘تُزال التكرارات من عملية الإدراج المُعادَة كما هو متوقّع.
SELECT 'third attempt';
INSERT INTO dst SELECT
1 AS key,
'b' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';
SELECT
'from dst',
*,
_part
FROM dst
ORDER BY all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 0 │ A │ all_2_2_0 │
│ from dst │ 0 │ A │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘تُعامَل عملية الإدراج تلك أيضًا على أنها مكررة، رغم أنها تحتوي على بيانات مُدرجة مختلفة. لاحظ أن insert_deduplication_token له أولوية أعلى: لا يستخدم ClickHouse قيمة hash للبيانات عند توفير insert_deduplication_token.
تُنتِج عمليات إدراج مختلفة البيانات نفسها بعد التحويل في الجدول الأساسي للعرض المادي
CREATE TABLE dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
CREATE MATERIALIZED VIEW mv_dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000
AS SELECT
0 AS key,
value AS value
FROM dst;
SET deduplicate_blocks_in_dependent_materialized_views=1;
select 'first attempt';
INSERT INTO dst VALUES (1, 'A');
SELECT
'from dst',
*,
_part
FROM dst
ORDER by all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 1 │ A │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘SELECT
'from mv_dst',
*,
_part
FROM mv_dst
ORDER by all;┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst │ 0 │ A │ all_0_0_0 │
└───────────────┴─────┴───────┴───────────┘select 'second attempt';
INSERT INTO dst VALUES (2, 'A');
SELECT
'from dst',
*,
_part
FROM dst
ORDER by all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 1 │ A │ all_0_0_0 │
│ from dst │ 2 │ A │ all_1_1_0 │
└────────────┴─────┴───────┴───────────┘SELECT
'from mv_dst',
*,
_part
FROM mv_dst
ORDER by all;┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst │ 0 │ A │ all_0_0_0 │
│ from mv_dst │ 0 │ A │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘نُدرِج بيانات مختلفة في كل مرة. ومع ذلك، تُدرَج البيانات نفسها في جدول mv_dst. لا تُزال التكرارات لأن بيانات المصدر كانت مختلفة.
عمليات إدراج مختلفة من عروض مادية إلى جدول أساسي واحد ببيانات متكافئة
CREATE TABLE dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
CREATE TABLE mv_dst
(
`key` Int64,
`value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;
CREATE MATERIALIZED VIEW mv_first
TO mv_dst
AS SELECT
0 AS key,
value AS value
FROM dst;
CREATE MATERIALIZED VIEW mv_second
TO mv_dst
AS SELECT
0 AS key,
value AS value
FROM dst;
SET deduplicate_blocks_in_dependent_materialized_views=1;
select 'first attempt';
INSERT INTO dst VALUES (1, 'A');
SELECT
'from dst',
*,
_part
FROM dst
ORDER by all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 1 │ A │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘SELECT
'from mv_dst',
*,
_part
FROM mv_dst
ORDER by all;┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst │ 0 │ A │ all_0_0_0 │
│ from mv_dst │ 0 │ A │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘تم إدراج كتلتين متساويتين إلى الجدول mv_dst (كما هو متوقع).
SELECT 'second attempt';
INSERT INTO dst VALUES (1, 'A');
SELECT
'from dst',
*,
_part
FROM dst
ORDER BY all;┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst │ 1 │ A │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘SELECT
'from mv_dst',
*,
_part
FROM mv_dst
ORDER by all;┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst │ 0 │ A │ all_0_0_0 │
│ from mv_dst │ 0 │ A │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘تُزال تكرارات عملية إعادة المحاولة تلك في كلا الجدولين dst وmv_dst.