সার্ভার পুনঃসূচনা করার পরে ইনোডব ডাটাবেসে অটো_সন্ট্রিমেন্ট আইডি পুনরায় সেট করা প্রতিরোধ করুন


11

আমি সম্প্রতি পড়েছি যে যখন সার্ভারটি পুনরায় চালু হয় তখন ইনোডিবি কীভাবে অটোপ্রেমেন্ট মানটিকে পুনরায় গণনা করে, আইডি তালিকার উচ্চ প্রান্তের কোনও রেকর্ড তাদের আইডি পুনরায় ব্যবহার করতে পারে।

সাধারণত, এটি কোনও সমস্যা নয়, কারণ যখন ব্যবহারকারী কোনও আইডি যুক্ত সমস্ত জিনিস মুছে ফেলা হয় তখন অন্যান্য টেবিল থেকেও মুছে ফেলা হয়।

তবে আমি ইচ্ছাকৃতভাবে তাদের ফোরামের পোস্টগুলি এতিম রেখে যাচ্ছি, "পোস্ট করা = ব্যবহারকারী # 123 =" হিসাবে লেবেলযুক্ত, যাতে অতীতের কথোপকথনগুলি বজায় থাকে। স্পষ্টতই, কোনও আইডি আবার ব্যবহার করা উচিত, এটি সমস্যা হবে।

আমি এই সমস্যাটি আগে কখনও পাইনি কারণ সেখানে সর্বদা যথেষ্ট নতুন ব্যবহারকারী থাকতেন যাতে কোনও আইডি এভাবে ব্যবহার করা সম্ভব হয় না। তবে আমার নতুন প্রকল্পে সাইনআপগুলি বিরল এবং নিষ্ক্রিয় ব্যবহারকারী মুছে ফেলা প্রায়শই হয় (বিশেষত যেহেতু "ওপেন আলফা" অ্যাকাউন্টগুলি পূর্বরূপ হিসাবে কেবল তিন দিনের জন্য স্থায়ী হয়), এবং এই জাতীয় আইডি পুনরায় ব্যবহার এখন তিনটির জন্য তিনটি ঘটেছে।

আমি অন্য কোথাও অটোপ্রেমেন্টের জন্য সঠিক মানটি সংরক্ষণ করে এবং অভ্যন্তরীণ মানের উপর নির্ভর করার পরিবর্তে এটি ব্যবহার করে সমস্যাটি স্থির করেছি। InnoDB আসল সর্বশেষ মানটি মনে রাখার কোন উপায় আছে?


আপনার পড়া নিবন্ধটি কি আছে?
gbn

@gbn dev.mysql.com/doc/refman/5.1/en/… নিবন্ধটির লিঙ্ক
নবীন কুমার


টেবিলের টেবিলের নামটি ENGINE = MyISAM আমার জন্য কাজ করে। আমাদের টেবিলটি সর্বদা খুব ছোট রাখা হয়, সুতরাং InnoDB এর দরকার নেই।

1
@ কুইকফিক্স কেন কাজ করে সে সম্পর্কে আপনার কিছু বিশদ যুক্ত করা উচিত ।
ম্যাক্স ভার্নন

উত্তর:


5

(কখনই মুছে না দিয়ে বিষয়টি এড়ানো)

যেহেতু আপনি "Posted by =User #123="ব্যবহারকারীকে মুছে ফেলার পরে আপনি তথ্যটি রাখতে চান id=123, আপনি ব্যবহারকারীদের ডেটা সংরক্ষণ করার জন্য 2 টি টেবিল ব্যবহার করার বিষয়েও বিবেচনা করতে পারেন। Activeব্যবহারকারীদের জন্য একটি এবং সবার জন্য একটি (সক্রিয় ব্যবহারকারীদের থেকে মুছে ফেলা সমেত)। এবং AllUserটেবিল থেকে এই আইডিগুলি কখনই মুছবেন না :

CREATE TABLE AllUser
( user_id INT AUTO_INCREMENT
, ...
, PRIMARY KEY (user_id)
) ;

------
--- Forum posts FK should reference the `AllUser` table

CREATE TABLE ActiveUser
( user_id INT 
, ...
, PRIMARY KEY (user_id)
, FOREIGN KEY (user_id)
    REFERENCES AllUser (user_id)
) ;

------
--- All other FKs should reference the `ActiveUser` table

এটি অবশ্যই সন্নিবেশ করা নতুন ব্যবহারকারীর ক্রিয়াকে জটিল করবে। যে কোনও নতুন ব্যবহারকারীর অর্থ 2 টি সন্নিবেশ করা উচিত, প্রতিটি সারণীতে একটি করে। কোনও ব্যবহারকারীকে মুছে ফেলা হবে ActiveUserকেবল টেবিল থেকে মুছে ফেলা । ফোরামের পোস্টগুলি বাদ দিয়ে সমস্ত এফকে ক্যাসকেডিং দিয়ে মুছে ফেলা হবে, যা Alluserটেবিলটি উল্লেখ করা হবে (যেখানে কোনও মুছে ফেলা হবে না)।


4

অটো_সংশোধন বিকল্পের সাহায্যে সমস্ত কলাম রেকর্ড করতে তথ্যের_সেমি.টেবেলগুলি ব্যবহার করা ছাড়া এটি করার কোনও প্রাকৃতিক উপায় নেই।

আপনি নিম্নলিখিত হিসাবে এই কলামগুলি সংগ্রহ করতে পারে:

CREATE TABLE mysql.my_autoinc ENGINE=MyISAM
SELECT table_schema,table_name,auto_increment
FROM information_schema.tables WHERE 1=2;
ALTER TABLE mysql.my_autoinc ADD PRIMARY KEY (table_schema,table_name);
INSERT INTO mysql.my_autoinc
SELECT table_schema,table_name,auto_increment
FROM information_schema.tables WHERE auto_increment IS NOT NULL;

এমন একটি স্ক্রিপ্ট তৈরি করুন যা স্বতঃসংযোগ মানগুলিকে পুনরায় সেট করবে

AUTOINC_SCRIPT=/var/lib/mysql/ResetAutoInc.sql
mysql -u... -p... -AN -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' AUTO_INCREMENT=',auto_increment,';') FROM mysql.my_autoinc" > ${AUTOINC_SCRIPT}

তারপরে আপনি দুটি কাজের একটি করতে পারেন:

বিকল্প # 1: স্টার্টআপের পরে ম্যানুয়ালি স্ক্রিপ্ট চালান

mysql> source /var/lib/mysql/ResetAutoInc.sql

বিকল্প # 2: সংযোগের অনুমতি দেওয়ার আগে মাইএসকিএলডি স্ক্রিপ্ট সম্পাদন করুন

আপনাকে এই বিকল্পটি যুক্ত করতে হবে

[mysqld]
init-file=/var/lib/mysql/ResetAutoInc.sql

এইভাবে, যতবারই আপনি মাইএসকিএল পুনরায় চালু করবেন, এই স্ক্রিপ্টটি শুরুতে কার্যকর করা হবে। আপনাকে পরিকল্পিত মাইএসকিএল পুনঃসূচনা করার আগে /var/lib/mysql/ResetAutoInc.sql পুনরায় জেনারেট করতে হবে।


3

5.5 ডক্স স্বয়ংক্রিয় বৃদ্ধি মান অন্যত্র সংরক্ষণকারী পরামর্শ যদি আপনি ইতিমধ্যেই আছে হিসাবে।

বিকল্প সমাধান হ'ল একটি সিক্যুয়েন্স অনুকরণ করা যাতে আপনি আসল টেবিলের মধ্যে স্বয়ংক্রিয়-বৃদ্ধি ব্যবহার না করেন। এই হয়েছে তাই আগে আলোচনা এবং আবারমাইএসকিউএল পারফরমেন্স ব্লগ এটা উল্লেখ করা হয়।

অন্য আরডিবিএমএসের স্ক্রু করে অন্য মাইএসকিউএল ডেটা ...


2

কেবল ব্যবহারকারীকে মুছবেন না। রিলেশনাল অখণ্ডতা আরও গুরুত্বপূর্ণ। আপনার যদি গোপনীয়তার কারণে বা যাই হোক না কেন, কেবল ব্যবহারকারী নামটি 'মুছে ফেলা' তে পরিবর্তন করুন এবং অন্য কোনও ক্ষেত্র সাফ করুন।


1

এটি একটি পুরানো প্রশ্ন এবং এখনও প্রাসঙ্গিক।

1) এই আচরণটি Mysql 8.0 এ স্থির করা হচ্ছে।

২) একটি সমাধান হ'ল AUTO_INCREMENT কে একটি নির্দিষ্ট মানের aboveর্ধ্বে রাখার জন্য আপনার ডেটাতে একটি ডামি সারি ব্যবহার করা। আপনি কী সংরক্ষণ করছেন তার উপর নির্ভর করে অতি সুবিধাজনক নয়, তবে কিছু ক্ষেত্রে এটি একটি সহজ সমাধান।


0

এই পোস্টের নির্দেশের উপর ভিত্তি করে আমাদের নিজস্ব সিস্টেমের জন্য এটি একটি বহির্মুখী সমাধানের প্রয়োজন ছিল। এটি যদি কাউকে আরও সহজ উপায়ে তাদের লক্ষ্যে পৌঁছাতে সহায়তা করতে পারে।

আমাদের সিস্টেমটি মুছে ফেলা আইটেমগুলি সংরক্ষণ করতে একটি সমাধিস্টোন টেবিলের প্যাটার্ন ব্যবহার করে কারণ আমরা সংযোগ বিচ্ছিন্ন সিস্টেমে 2 টি উপায় সিঙ্ক করি, তাই আমরা এই কোডটি তাদের লাইভ টেবিলের সাথে সমাধিপাথরের টেবিলগুলির সাথে মেলে এবং সম্ভাব্য সর্বোচ্চ মান বের করতে :) ব্যবহার করি :)

DROP PROCEDURE IF EXISTS `reset_auto_increments`;
DELIMITER $
CREATE PROCEDURE reset_auto_increments()
BEGIN

    DECLARE done INT DEFAULT 0;
    DECLARE schemaName VARCHAR(255) DEFAULT '';
    DECLARE liveTableName VARCHAR(255) DEFAULT '';
    DECLARE tombstoneTableName VARCHAR(255) DEFAULT '';
    DECLARE liveAutoIncrement INT DEFAULT 0;
    DECLARE tombstoneAutoIncrement INT DEFAULT 0;
    DECLARE newAutoIncrement INT DEFAULT 0;

    DECLARE autoIncrementPairs CURSOR FOR 
        SELECT
            liveTables.TABLE_SCHEMA AS schemaName,
            liveTables.TABLE_NAME AS liveTable, 
            tombstoneTables.TABLE_NAME AS tombstoneTable,
            liveTables.AUTO_INCREMENT AS live_auto_increment,
            tombstoneTables.AUTO_INCREMENT AS tombstone_auto_increment,
            GREATEST(liveTables.AUTO_INCREMENT, tombstoneTables.AUTO_INCREMENT) AS new_auto_increment
        FROM 
            information_schema.tables AS liveTables
            JOIN information_schema.tables AS tombstoneTables
                ON liveTables.TABLE_SCHEMA = tombstoneTables.TABLE_SCHEMA
                    AND CONCAT('deleted', UCASE(LEFT(liveTables.TABLE_NAME, 1)), SUBSTRING(liveTables.TABLE_NAME, 2))
                        = tombstoneTables.TABLE_NAME
        WHERE
            GREATEST(liveTables.AUTO_INCREMENT, tombstoneTables.AUTO_INCREMENT) IS NOT NULL;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    SET done = 0;

    SET schemaName = '';
    SET liveTableName = '';
    SET tombstoneTableName = '';
    SET liveAutoIncrement = 0;
    SET tombstoneAutoIncrement = 0;
    SET newAutoIncrement = 0;

    OPEN autoIncrementPairs;
    REPEAT

        FETCH autoIncrementPairs INTO 
            schemaName, 
            liveTableName, 
            tombstoneTableName, 
            liveAutoIncrement, 
            tombstoneAutoIncrement, 
            newAutoIncrement;

        SET @statement = CONCAT('ALTER TABLE ', schemaName, '.', liveTableName, ' AUTO_INCREMENT=', newAutoIncrement);
        PREPARE updateAutoIncrementStatement FROM @statement;
        EXECUTE updateAutoIncrementStatement;
        DEALLOCATE PREPARE updateAutoIncrementStatement;

    UNTIL done END REPEAT;

    CLOSE autoIncrementPairs;

END$

DELIMITER ;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.