تقترب بيانات قاعدة البيانات في المشروع الذي تم إطلاقه مؤخرًا من التشبع. تقترب أكبر بيانات الجدول من 3000 واط ، وهناك العديد من الجداول التي تحتوي على ملايين البيانات. يتطلب المشروع ألا يتجاوز وقت قراءة البيانات 0.05 ثانية ، لكن الموقف الفعلي لا يفي بالمتطلبات. شرح فهرسة واستخدام تقنية ذاكرة التخزين المؤقت Redis و Ehcache لم تعد تفي بالمتطلبات. لذلك ، بدأنا في استخدام تقنية القراءة والكتابة. ربما عندما يتجاوز حجم البيانات 100 مليون أو أكثر في المستقبل ، نحتاج إلى النظر في نشر قواعد البيانات الموزعة. ومع ذلك ، في الوقت الحاضر ، اقرأ وكتابة الفصل + Cache + INDEX + Partition + SQL Optimization + يمكن أن تفي موازنة التحميل بأعمال الاستعلام التي تضم 100 مليون مجلد للبيانات. دعنا نلقي نظرة على الخطوات لاستخدام الربيع لتحقيق فصل القراءة والكتابة:
1. الخلفية
يتمثل تطبيقنا العام في "قراءة المزيد وكتابة أقل" لقواعد البيانات ، مما يعني أن الضغط على قاعدة البيانات لقراءة البيانات مرتفع نسبيًا. فكرة واحدة هي استخدام حل كتلة قاعدة البيانات.
واحد منهم هو المكتبة الرئيسية ، المسؤولة عن كتابة البيانات ، التي نسميها: كتابة المكتبة ؛
الآخرون جميعهم من المكتبة ، المسؤولة عن قراءة البيانات ، التي نسميها: قراءة المكتبة ؛
لذا ، فإن متطلباتنا هي:
1. بيانات مكتبة القراءة ومكتبة الكتابة متسقة ؛ (هذه مشكلة مهمة للغاية. يجب معالجة معالجة منطق العمل في طبقة الخدمة ، وليس على مستوى DAO أو MAPPER)
2. عند كتابة البيانات ، يجب عليك كتابتها إلى مكتبة الكتابة ؛
3. يجب أن تذهب إلى مكتبة القراءة لقراءة البيانات ؛
2. خطة
هناك حلان لحل فصل القراءة والكتابة: حل طبقة التطبيق وحل الوسيطة.
2.1. حل طبقة التطبيق:
ميزة:
1. مصادر بيانات متعددة سهلة التبديل ويتم إكمالها تلقائيًا بواسطة البرنامج ؛
2. لا يلزم وجود برامج وسيطة.
3. من الناحية النظرية ، دعم أي قاعدة بيانات ؛
عيب:
1. لا يشارك المبرمجين ، والتشغيل والصيانة ؛
2. لا يمكن تحقيق زيادة مصادر البيانات ديناميكيًا ؛
2.2. حل الوسيطة
إيجابيات وسلبيات:
ميزة:
1. يمكن لبرنامج المصدر تحقيق فصل القراءة والكتابة دون أي تغييرات ؛
2. لا تتطلب إضافة مصادر البيانات ديناميكيًا إعادة تشغيل البرنامج ؛
عيب:
1. تعتمد البرامج على البرامج الوسيطة ، مما يجعل من الصعب تبديل قواعد البيانات ؛
2. يتم استخدام الوسيطة كعامل عبور ، وانخفض الأداء ؛
3. استخدم الربيع للتنفيذ بناءً على طبقة التطبيق
3.1. مبدأ
قبل إدخال الخدمة ، استخدم AOP لإصدار حكم ، سواء كنت تستخدم مكتبة الكتابة أو مكتبة قراءة ، يمكن الحكم على أساس الحكم بناءً على اسم الطريقة ، مثل تلك التي تبدأ بالاستعلام ، البحث ، Get ، وما إلى ذلك ، ومكتبة الكتابة الأخرى.
3.2. DynamicDataSource
استيراد org.springframework.jdbc.datasource.lookup.abstractroutingDataSource ؛/*** تحديد مصادر البيانات الديناميكية وتنفيذ ArtCractRoutingDataSource المقدمة من Spring Integration. تحتاج فقط إلى تنفيذ طريقة deternecurrentlookupkey * * نظرًا لأن DynamicDataSource عبارة عن مقر مفردة وعلم خيوط ، يتم استخدام threadlocal لضمان سلامة مؤشرات الترابط ، والتي يتم الانتهاء منها بواسطة حامل DynamicDataSourceholder. * * Author Zhijun * */Class Public Class DynamicDataSource يمتد ArgtRactRoutingDataSource {Override المحمي DETERNECURRENTOLKUPKEY () {// استخدام DynamicDataSourceKey () }} 3.3. DynamicDataSourceHolder
/** * * استخدم تقنية ThreadLocal لتسجيل مفتاح مصدر البيانات في مؤشر الترابط الحالي * * Author Zhijun * */public Class DynamicDataSourceHolder {// اكتب مصدر البيانات المقابل للمكتبة الخاصة Static String String Master = "Master" ؛ // اقرأ مصدر البيانات المقابل للمكتبة الثابتة Static Final String = "Slave" ؛ // استخدم ThreadLocal لتسجيل مصدر بيانات مؤشر ترابط مؤشر الترابط النهائي الحالي الثابت <string> حامل = new threadlocal <string> () ؛ / ** * قم بتعيين مفتاح مصدر البيانات * @param مفتاح */ public static void putDataSourceKey (مفتاح السلسلة) {holder.set (key) ؛ } / ** * احصل على مفتاح مصدر البيانات * @regurn * / سلسلة ثابتة عامة getDataSourceKey () {return holder.get () ؛ } / *** مكتبة كتابة Markup* / public static void markmaster () {putDataSourceKey (master) ؛ } / *** Markup Read Library* / public static void markslave () {putDataSourceKey (slave) ؛ }} 3.4. DataSourCeaspect
استيراد org.apache.commons.lang3.stringUtils ؛ استيراد org.aspectj.lang.joinpoint ؛/** * حدد قسم AOP لمصدر البيانات ، والحكم على ما إذا كان الوقت قد حان لقراءة المكتبة أو كتابة المكتبة من خلال execute اسم SERVICE * execute * execute * execute * execute * execute * execute * execute public void قبل (point point) {// احصل على اسم الطريقة التي تم تنفيذها حاليًا methodName = point.getSignature (). getName () ؛ if (isslave (methodName)) {// mark as read armicdataSourceHolder.markslave () ؛ } else {// mark as write library dynamicdataSourceHolder.markmaster () ؛ }} / ** * حدد ما إذا كانت مكتبة قراءة * * param methodname * @return * / private boolean isslave (String methodName) {// method method Quary ، find ، get ، return stringutils.startswithany (methodname ، "query" ، "find" ، "get") ؛ }}3.5. تكوين 2 مصادر البيانات
3.5.1. JDBC.Properties
jdbc.master.driver = com.mysql.jdbc.driverjdbc.master.url = jdbc: mysql: //127.0.0.1: 3306/mybatis_1128؟ useUnicode = true & ch aracterEncoding = UTF8 & AutorEconnect = true & loomtliqueries = truejdbc.master.username = rootjdbc.master.password = 123456jd bc.slave01.driver = com.mysql.jdbc.driverjdbc.slave01.url = jdbc: mysql: //127.0.0.1: 3307/mybatis_1128؟ useUnicode = true & ch aracterencoding = utf8 & autoreconnect = true & allomeRiqueries = truejdbc.slave01.username = rootjdbc.slave01.password = 123456
3.5.2. تحديد تجمع الاتصال
<!-تكوين تجمع الاتصال-> <bean id = "masterdatasource" تدمير method = "close"> <!-DATABASE DRIVER-> <property name = "driverclass" value = "$ {jdbc.master.driver}" /> <! اسم المستخدم لقاعدة البيانات-> <property name = "username" value = "$ {jdbc.master.username}" /> <!-كلمة مرور قاعدة البيانات-> <property name = "password" value = "$ {jdbc.master.password}" /> <!- الوحدة جزء. القيمة الافتراضية هي 240. إذا كنت تريد الإلغاء ، فقم بتعيينها على 0. الوحدة جزء. القيمة الافتراضية هي 60. إذا كنت تريد البقاء على قيد الحياة إلى الأبد ، فقم بالتعيين على 0.-> <property name = "idlemaxage" value = "30" /> <!-الحد الأقصى لعدد الاتصالات لكل قسم-> <اسم propert الحد الأدنى لعدد الاتصالات لكل قسم-> <name property = "maxConnectionSperPartition" value = "150" /> <!-الحد الأدنى لعدد الاتصالات لكل قسم-> <property name = "minconnectionsprartition" value = "5" /> </bean> <! <property name = "driverclass" value = "$ {jdbc.slave01.driver}" /> <!-jdbcurl للسائق المقابل-> <property name = "jdbcurl" value = "$ {jdbc.slave01.url}" /> <! value = "$ {jdbc.slave01.Username}" /> <!-كلمة مرور قاعدة البيانات-> <property name = "password" value = "$ {jdbc.slave01.password}" /> <!-تحقق من وقت الفاصل الزمني لاتصالات الخمول في تجمع قاعدة البيانات. الوحدة جزء. القيمة الافتراضية هي 240. إذا كنت ترغب في الإلغاء ، فقم بتعيينها على 0.-> <property name = "idleconnecteStperiod" value = "60" /> <!-الحد الأقصى لوقت البقاء على قيد الحياة للروابط غير المستخدمة في مجموعة الاتصال. الوحدة جزء. القيمة الافتراضية هي 60. إذا كنت تريد البقاء على قيد الحياة إلى الأبد ، فقم بالتعيين على 0.-> <property name = "idlemaxage" value = "30" /> <!-الحد الأقصى لعدد الاتصالات لكل قسم-> <property name = "maxConnectionSperPartition" value = "150" /> <! 3.5.3. تحديد مصدر البيانات
<!-حدد مصدر البيانات واستخدم مصدر البيانات الذي تقوم بتطبيقه-> <bean id = "datasource"> <!-تعيين مصادر بيانات متعددة-> <property name = "targetdatasources"> <map key-type = "java.lang.string"> <! key = "slave" value-ref = "slave01DataSource"/> </map> </property> <!-قم بتعيين مصدر البيانات الافتراضي ، هنا مكتبة الكتابة الافتراضية-> <property name = "defaultTargetDataSource" ref = "masterdatasource"/> </ban>
3.6. تكوين إدارة المعاملات وتبديل أسطح مصدر البيانات ديناميكيًا
3.6.1. تحديد مدير المعاملات
<!-تعريف مدير المعاملات-> <bean id = "TransactionManager"> <property name = "datasource" ref = "datasource" /> </bean>
3.6.2. تحديد سياسات المعاملات
<!-تحديد سياسة المعاملة-> <tx: معرف المشورة = "TxAdvice" المعاملة-ماناجير = "TransactionManager"> <tx: السمات> <!-تحديد طرق الاستعلام هي القراءة فقط-> <tx: method name = "query*" end-only = "true" /> <tx: method* read-only = "true" /> <!-تقوم المكتبة الرئيسية بإجراء العمليات ، ويتم تعريف سلوك انتشار المعاملة على أنه السلوك الافتراضي-> <tx: method name = "save*" spection = "required" /> <tx: method name = "update* name = "*"/> </tx: entributes> </tx: نصيحة>
3.6.3. تحديد الوجه
<!-حدد معالج قسم AOP-> <bean id = "dataSourCeaspect" /> <aop: config> <!-تحديد الأقسام ، جميع أساليب جميع الخدمات-> <aOP: pointcut id = "txpointcut" expression = "execution (*xx.xxxxxxx.service.*.*. <aOP: Advisor excloy-ref = "txAdvice" pointcut-ref = "txpointcut" /> <!-قم بتطبيق القسم على معالج قسم مخصص ، -9999 يضمن أن القسم له أولوية قصوى-> قبل "expoint /" expoint-ref = "txpoint =" txpoint-ref = </aop: Side> </aop: config>
4. تحسين تنفيذ القسم واستخدام قواعد سياسة المعاملات
في التنفيذ السابق ، سنطابق اسم الطريقة بدلاً من استخدام التعريف في سياسة المعاملة ، وسنستخدم القاعدة المطابقة في سياسة إدارة المعاملات.
4.1. تكوين تحسين
<!-حدد معالج قسم AOP-> <bean id = "dataSourCeaspect"> <!-حدد سياسة المعاملة-> <property name = "txadvice" ref = "txadvice"/> <!-حدد بادئة طريقة العبيد (غير مطلوب)-> <property name = "slavemethodstart" value = "query ، get"/> </
4.2. تحسين التنفيذ
استيراد java.lang.reflect.field ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد java.util.map ؛ import org.apache.commons.lang3.stringutils ؛ import org.aspectj.lang.joinpoint ؛ org.springframework.transaction.Interceptor.TransActionAttribute ؛ استيراد org.springframework.transaction.Interceptor.TransactionAttributesource ؛ misp.springframework.transaction.Interceptor.transactionInterceptor org.springframework.util.reflectionutils ؛/*** يحدد قسم AOP لمصدر البيانات ، والذي يتحكم في استخدام الماجستير أو العبد. * * إذا تم تكوين سياسة المعاملات في إدارة المعاملات ، فإن طريقة وضع علامة على قراءتها في سياسة المعاملة التي تم تكوينها هي استخدام الرقيق ، والآخر يستخدم Master. * * إذا لم يكن هناك سياسة لتكوين إدارة المعاملات ، يتم اعتماد مبدأ مطابقة الأسماء ، ويتم استخدام العبيد كبدء بالاستعلام ، والعثور ، والاستمتاع ، ويتم استخدام طرق أخرى كماجستير. * * Author Zhijun * */public class dataSourCeaspect {private list <string> slavemethodpattern = new ArrayList <string> () ؛ السلسلة النهائية الثابتة الخاصة [] DefaultSlaVeMethodStart = New String [] {"Query" ، "Find" ، "GET"} ؛ سلسلة خاصة [] slavemethodstart ؛ / ** * اقرأ السياسات في إدارة المعاملات * * param txAdvice * Throws استثناء */ suppressWarnings ("Unchecked") public void settxadvice (TransactionInterceptor txAdvice) يلقي الاستثناء {if (txadvice == null) {// لا يتم تكوين سياسة إدارة المعاملات ؛ } // الحصول على معلومات تكوين السياسة من TXAdvice TransactionAtributesource TransactionAttributesource = txAdvice.GetTransactionAtributesource () ؛ if (! (TransactionAttributesource مثيل namematchTransActionAttributesource)) {return ؛ } // استخدم تقنية الانعكاس للحصول على قيمة سمة namemap في كائن NameMatchTransactionAttributesource namematchTransActionAttributesource matchTransActionAttributesource = (NameMatchTransactionAtributesource) TransactionAttributesource ؛ Field namemapfield = ReflectionUtils.findfield (namematchTransActionAttributesource.class ، "namemap") ؛ namemapfield.setAccable (true) ؛ // قم بتعيين هذا الحقل للوصول إلى // الحصول على قيمة namemap <string ، TransactionAttribute> map = (map <string ، TransactionAttribute>) namemapfield.get (MatchTransactionAtributesource) ؛ // TransactionAttribute> الإدخال: map.entryset ()) {if (! entry.getValue (). isReadOnly ()) {// بعد الحكم ، يتم تعريف السياسة القراءة قبل إضافتها إلى slavemethodpattern المتابعة ؛ } slavemethodpattern.add (enter.getKey ()) ؛ }} / *** تنفيذ قبل إدخال طريقة الخدمة* Param Point Face Object* / public void قبل (نقطة JoinPoint) {// الحصول على اسم الطريقة التي تم تنفيذها حاليًا methodName = point.getSignature (). getName () ؛ isslave منطقية = خطأ ؛ if (slavemethodpattern.isempty ()) {// لا توجد سياسة معاملة تم تكوينها في حاوية الربيع الحالية ، وطريقة مطابقة اسم الطريقة isslave = isslave (methodName) ؛ } آخر {// استخدم قواعد السياسة لتتطابق مع (String medname: slavemethodpattern) {if (isMatch (methodName ، medname)) {isslave = true ؛ استراحة؛ }}}} if (isslave) {// mark as read library dynamicDataSourceHolder.markslave () ؛ } else {// mark as write library dynamicdataSourceHolder.markmaster () ؛ }} / ** * حدد ما إذا كانت مكتبة قراءة * * param methodname * @return * / private boolean isslave (String methodName) {// method name يبدأ بالاستعلام ، العثور على stringutils.startswithany (methodname ، getLaveMethodStart ()) ؛ } /** * Wildcard Matching * * return إذا كان اسم الطريقة المحددة يطابق الاسم المعين. *<p>*يتحقق التنفيذ الافتراضي لـ "XXX*" و "*XXX" و "*XXX*" ، بالإضافة إلى المساواة المباشرة*. يمكن تجاوزها في الفئات الفرعية. * * param methodName اسم طريقة الفئة * param meddName اسم في الواصف * return إذا كانت الأسماء تتطابق * see org.springframework.util.patternmatchutils#simplematch (سلسلة ، سلسلة) MethodName) ؛ } / *** بادئة اسم الأسلوب للعبّد المحدد* param slavemethodstart* / public void setSlavemethodStart (string [] slavemethodstart) {this.slavemethodstart = slavemethodstart ؛ } السلسلة العامة [] getSlaVeMethodStart () {if (this.slaveMethodStart == null) {// غير محدد ، استخدم الافتراض الافتراضي الافتراضي defaultslavemethodstart ؛ } إرجاع slavemethodstart ؛ }}5. تنفيذ ماجستير وعبيد متعددين
في العديد من سيناريوهات الاستخدام العملي ، نستخدم بنية "ماجستير ، عبيد متعدد" ، لذلك نحن ندعم الآن هذه البنية ، ونحتاج حاليًا إلى تعديل DynamicDataSource.
5.1. تطبيق
استيراد java.lang.reflect.field ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ java.util.map ؛ import java.util.concurrent.atomic.atomicinteger ؛ import javax.sql.datasource ؛ import org.slf4j.logger ؛ org.springframework.jdbc.datasource.lookup.abstractroutingDataSource ؛ استيراد org.springframework.util.reflectionutils ؛/** * تحدد مصادر البيانات الديناميكية وتنفيذ abstractrouting يتم استخدام ThreadLocal المفرد وعمليات الترجمة الخيطية لضمان سلامة مؤشرات الترابط ، والتي يتم الانتهاء منها بواسطة حامل DynamicDataSourceHolder. * * Author Zhijun * */Class Public DynamicDataSource يمتد ArgtRactRoutingDataSource {private Static Final Logger = loggerfactory.getLogger (DynamicDataSource.Class) ؛ عدد صحيح خاص slavecount ؛ // Count Count ، في البداية -1 ، AtomicInteger هو عداد AtomicInteger الخاص بآمن واحد = جديد AtomicInteger (-1) ؛ // قم بتسجيل القائمة الخاصة الرئيسية <Object> slavedataSources = new ArrayList <Object> (0) ؛ Override محمية كائن محمي DETRIMINECURRENTOKTOKEUPKEY () {// استخدم DynamicDataSourceHolder لضمان سلامة مؤشر الترابط والحصول على مفتاح مصدر البيانات في مؤشر الترابط الحالي إذا (DynamicDataSourceHolder.ismaster ()) if (logger.isdebugenabled ()) {logger.debug ("مفتاح مصدر البيانات الحالي هو:" + مفتاح) ؛ } مفتاح العودة ؛ } مفتاح الكائن = getSlaveKey () ؛ if (logger.isdebugenabled ()) {logger.debug ("مفتاح مصدر البيانات الحالي هو:" + مفتاح) ؛ } مفتاح العودة ؛ } suppressWarnings ("Unchecked") Override public void بعد propertiesset () {super.afterpropertiesset () ؛ // بما أن خاصية ResolvedDataSources للفئة الأصل هي فئة فرعية خاصة لا يمكن الحصول عليها ، فأنت بحاجة إلى استخدام التأمل للحصول على حقل الحقل = ReflectionUtils.Findfield (ArgtRactRoutingDataSource.class ، "ResolvedDatasources") ؛ Field.SetAccessible (صحيح) ؛ // set accessibility try {map <object ، dataSource> resolvedDataSources = (map <object ، dataSource>) field.get (this) ؛ . لـ (map.entry <object ، dataSource> الإدخال: resolvedDataSources.entrySet ()) {if (dynamicDataSourceHolder.master.equals (intrad.getKey ())) {متابعة ؛ } slavedataSources.add (intpring.getKey ()) ؛ }} catch (استثناء e) {logger.error ("خطأ بعد propertiesset!" ، e) ؛ }} / ** * تطبيق خوارزمية الاقتراع * * * @RETURN * / كائن عام getSlaveKey () {// المشتركين الناتج هي: 0 ، 1 ، 2 ، 3 ... INTEGER INDEX = counter.incrementandget () ٪ slavecount ؛ if (counter.get ()> 9999) {// لتجنب تجاوز counter.set Range Range (-1) ؛ // Restore} return slavedataSources.get (index) ؛ }}6.
6.1. مبدأ
مبدأ نسخ MySQL Master (يسمى Master) Slave (يسمى العبد):
1. يسجل Master تغييرات البيانات في السجل الثنائي ، أي الملف المحدد بواسطة BIN LOG CONFIGTURATION
2. عبيد نسخة الماجستير الماجستير في سجل الترحيل الخاص به (سجل الترحيل)
3. سيؤدي أحداث إعادة صياغة العبيد في سجل الترحيل إلى تغيير البيانات التي تعكس نفسها (إعادة البيانات)
6.2. ما الذي يجب الانتباه إليه عند تكوين ماخ
1. إصدارات خادم DB الأساسي وقاعدة بيانات Slave DB Server هي نفسها
2. بيانات قاعدة البيانات الخاصة بخادم DB الرئيسي وخادم DB الرقيق متماثلون [هنا يمكنك استعادة النسخ الاحتياطي للماجستير على العبد ، أو يمكنك نسخ دليل بيانات Master مباشرة إلى دليل بيانات العبيد المقابل]
3. يتيح خادم DB الرئيسي سجلات ثنائية ، ويجب أن يكون خادم DB الرئيسي وخادم Slave DB Server فريدًا.
6.3. تكوين المكتبة الرئيسي (على غرار Windows ، Linux)
قد لا يكون لدى بعض الأصدقاء عنوان IP واضح للغاية ، اسم المستخدم وتكوين حساب قاعدة بيانات Master و Slave. فيما يلي تكوين Master and Slave الذي اختبرته. IPS كلها 127.0.0.1. بعد أن انتهيت من مثالي ، سأكتبه.
IP Master-slave هو مثال على التكوينات المختلفة. يمكنك استخدام هذا المثال لفهم طريقة التكوين بشكل أكثر حدًا.
تعديل تحت my.ini [mysqld] (وكذلك من المكتبة):
#تكرار ماجستير في العبد ، تكوين LOGH LOG-BIN = MySQL3306-BIN#حدد المكتبة الرئيسية Serveridserver-ID = 101#حدد قاعدة البيانات المتزامنة. إذا لم يتم تحديدها ، يتم مزامنة جميع قواعد البيانات binlog-do-db = mybatis_1128
(يجب أن يكون للأوامر التي تم إدخالها في My.Ini خطًا من المساحة أدناه ، وإلا فلن يتعرف عليه MySQL)
تنفيذ حالة استعلام بيان SQL: عرض الحالة الرئيسية
يجب تسجيل قيمة الموضع ، ويجب تعيين قيمة بدء التزامن في المكتبة.
اسمحوا لي أن أقول شيء آخر. إذا قمت بتنفيذ SHOW MASTER STATCE على MySQL واكتشف أن المحتوى الذي تم تكوينه في My.Ini لم ينجح. قد يكون أنك لم تختار ملف my.ini ، أو قد تكون أنك لم تعيد تشغيل الخدمة. من المحتمل جدًا أن يكون سببها الأخير.
لجعل التكوين ساري المفعول ، يجب عليك إيقاف تشغيل خدمة MySQL وإعادة تشغيلها.
كيفية إغلاق الخدمة:
افتح مفتاح الفوز ، أدخل Services.msc لاستدعاء الخدمة:
ابدأ sqlyog مرة أخرى ووجد أن التكوين قد بدأ سريانه.
6.4. إنشاء مستخدم متزامن في المكتبة الرئيسية
#AUNTIDERSITED USER SLAVE01 يستخدم 123456 كلمة مرور لتسجيل الدخول في MySQLGRANT REPLICATION SLAVE على *. * إلى "slave01'@'127.0.0.1" تم تحديده بواسطة "123456" ؛ امتيازات Flush ؛
6.5. التكوين من المكتبة
تعديل في my.ini:
#Specify ServerId ، طالما لم يتم تكراره ، يوجد تكوين واحد فقط من المكتبة ، ويتم تشغيل الآخرين في معرف خادم بيانات SQL = 102
ما يلي ينفذ SQL (ينفذ باستخدام حساب جذر العبد):
ChangematerTomater_Hot = '127.0.0.1' ، // Ql) Mater_Paword = '123456' ، Mater_port = 3306 ، Mater_log_file = 'myql3306-bin.000006' ، // filemate_log_po = 1120 ؛ // poition
#ابدأ تزامن الرقيق الرقيق ؛
فيما يلي طرق تكوين Master و Slave لجهاز كمبيوتر IP مختلفان:
نظام التشغيل حيث توجد قاعدة البيانات الرئيسية: Win7
إصدار قاعدة البيانات الأساسية: 5.0
عنوان IP لقاعدة البيانات الرئيسية: 192.168.1.111
من نظام التشغيل حيث توجد قاعدة البيانات: Linux
من إصدار البيانات: 5.0
عنوان IP من قاعدة البيانات: 192.168.1.112
بعد تقديم البيئة ، دعنا نتحدث عن خطوات التكوين:
1. تأكد من أن قاعدة البيانات الرئيسية هي بالضبط نفس قاعدة بيانات الرقيق.
على سبيل المثال: تحتوي قاعدة البيانات في قاعدة البيانات الرئيسية على جداول B و C و D ، وبالتالي يجب نقش قاعدة البيانات A و Tables B و C و D مع قالب.
2. إنشاء حساب متزامن على قاعدة البيانات الرئيسية.
نسخة الكود كما يلي:
منح العبد النسخ المتماثل ، ملف على *. * إلى 'mstest'@'192.168.1.112' تم تحديده بواسطة '123456' ؛
192.168.1.112: إنه عنوان IP الذي يتم تشغيله باستخدام المستخدم
MSTEST: هو اسم المستخدم الذي تم إنشاؤه حديثًا
123456: إنها كلمة مرور اسم المستخدم الذي تم إنشاؤه حديثًا
من الأفضل القيام بالتفسير التفصيلي للأمر أعلاه على Baidu. إذا كتبت كثيرًا ، فسيجعله أكثر وضوحًا.
3. تكوين my.ini من قاعدة البيانات الرئيسية (لأنها تحت النافذة ، إنها my.ini وليس my.cnf).
[mysqld] server-id = 1log-bin = logbinlog-do-db = mStest // لمزامنة قاعدة بيانات mStest ، إذا كنت تريد مزامنة قواعد البيانات المتعددة ، أضف بضع المزيد
4. تكوين my.cnf من قاعدة البيانات.
[mysqld] معرف الخادم = 2 Master-Host = 192.168.1.111111sermaster-user = mStest // الخطوة 1. إنشاء اسم المستخدم لكلمات المسار الرئيسي لـ account = 123456 // الخطوة 1. قواعد البيانات ، أضف عدد قليل من النسخ المتماثل do-db = اسم قاعدة البيانات النسخ المتماثل-ignore-db = mysql // قاعدة البيانات المراد تجاهلها
5. تحقق مما إذا كان ناجحًا
أدخل mysql وأدخل الأمر: عرض حالة الرقيق/g. سيتم عرض الصورة التالية. إذا كان كل من slave_io_running و slave_sql_running نعم ، فهذا يعني أن التزامن يمكن أن يكون بنجاح
6. اختبار البيانات المتزامنة.
أدخل قاعدة البيانات الرئيسية وأدخل الأمر: أدخل في قيم (اسم) واحد ('beijing') ؛
ثم أدخل أمر الإدخال من قاعدة البيانات: حدد * من واحد ؛
إذا تم استرداد البيانات من قاعدة البيانات في هذا الوقت ، فهذا يعني أن التزامن كان ناجحًا وسيتم تنفيذ السيد والعبد.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.