]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4373] Improve Mysql sflqCreateFlqPool6 performance
authorThomas Markwalder <tmark@isc.org>
Sun, 29 Mar 2026 17:08:12 +0000 (13:08 -0400)
committerThomas Markwalder <tmark@isc.org>
Tue, 31 Mar 2026 14:33:50 +0000 (14:33 +0000)
modified:
    /src/share/database/scripts/mysql/dhcpdb_create.mysql
    /src/share/database/scripts/mysql/upgrade_033_to_034.sh.in

src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/upgrade_033_to_034.sh.in

index f3896df752c9391b7374458663d3c057770b2fcb..e2920345de6e4ee61932196da9eca3e357339d49 100644 (file)
@@ -6884,26 +6884,34 @@ BEGIN
 
     -- Wipe out existing free addresses. This ensures we fix any mixed allocation entries.
     DELETE FROM free_lease6 WHERE bin_address >= bin_next_address and bin_address <= bin_end_address;
+    -- Enumerate the addresses into a temp table to use in a bulk insert.
+    DROP TEMPORARY TABLE IF EXISTS _flq6_candidates;
+    CREATE TEMPORARY TABLE _flq6_candidates (
+        bin_address BINARY(16) NOT NULL PRIMARY KEY,
+        address VARCHAR(45) NOT NULL
+    ) ENGINE=InnoDB;
 
-    -- Insert available leases into free_lease6 table.  If insert fails on
-    -- duplicate ignore it. MySQL doesn't provide math operations on
-    -- binrary(16) so we do it one address at time, using our own function
-    -- to increment the address/prefix.
     WHILE bin_next_address <= bin_end_address
     DO
-        SELECT address INTO lease_address FROM lease6
-            WHERE (address = bin_next_address AND lease6.state != 2
-                   AND (expire > now() OR valid_lifetime = 0xFFFFFFFF));
-
-        IF (found_rows() = 0)
-        THEN
-            INSERT IGNORE INTO free_lease6(address, bin_address)
-                VALUES (INET6_NTOA(bin_next_address), bin_next_address);
-        END IF;
-
+        INSERT INTO _flq6_candidates (bin_address, address)
+            VALUES (bin_next_address, INET6_NTOA(bin_next_address));
         SET bin_next_address = incrementV6Prefix(bin_next_address, p_delegated_len);
     END WHILE;
 
+    -- Bulk insert available leases into free_lease6 table. If insert fails on
+    -- duplicate ignore it.
+    INSERT IGNORE INTO free_lease6 (address, bin_address)
+        SELECT c.address, c.bin_address
+        FROM _flq6_candidates c
+        WHERE NOT EXISTS (
+            SELECT 1 FROM lease6 l
+            WHERE l.address = c.address
+              AND l.state != 2
+              AND (l.expire > now() OR l.valid_lifetime = 0xFFFFFFFF)
+        );
+
+    DROP TEMPORARY TABLE _flq6_candidates;
+
     -- Update the modification time in the flq_pool row.
     UPDATE flq_pool6 SET modification_ts = now()
         WHERE (start_address = p_start_address AND end_address = p_end_address);
index 814d3a05533a0eb680b80b72f366bcd85ed86f35..84882a05e4040112b50d3e84898d6abb4a586285 100755 (executable)
@@ -465,25 +465,34 @@ BEGIN
     -- Wipe out existing free addresses. This ensures we fix any mixed allocation entries.
     DELETE FROM free_lease6 WHERE bin_address >= bin_next_address and bin_address <= bin_end_address;
 
-    -- Insert available leases into free_lease6 table.  If insert fails on
-    -- duplicate ignore it. MySQL doesn't provide math operations on
-    -- binrary(16) so we do it one address at time, using our own function
-    -- to increment the address/prefix.
+    -- Enumerate the addresses into a temp table to use in a bulk insert.
+    DROP TEMPORARY TABLE IF EXISTS _flq6_candidates;
+    CREATE TEMPORARY TABLE _flq6_candidates (
+        bin_address BINARY(16) NOT NULL PRIMARY KEY,
+        address VARCHAR(45) NOT NULL
+    ) ENGINE=InnoDB;
+
     WHILE bin_next_address <= bin_end_address
     DO
-        SELECT address INTO lease_address FROM lease6
-            WHERE (address = bin_next_address AND lease6.state != 2
-                   AND (expire > now() OR valid_lifetime = 0xFFFFFFFF));
-
-        IF (found_rows() = 0)
-        THEN
-            INSERT IGNORE INTO free_lease6(address, bin_address)
-                VALUES (INET6_NTOA(bin_next_address), bin_next_address);
-        END IF;
-
+        INSERT INTO _flq6_candidates (bin_address, address)
+            VALUES (bin_next_address, INET6_NTOA(bin_next_address));
         SET bin_next_address = incrementV6Prefix(bin_next_address, p_delegated_len);
     END WHILE;
 
+    -- Bulk insert available leases into free_lease6 table. If insert fails on
+    -- duplicate ignore it.
+    INSERT IGNORE INTO free_lease6 (address, bin_address)
+        SELECT c.address, c.bin_address
+        FROM _flq6_candidates c
+        WHERE NOT EXISTS (
+            SELECT 1 FROM lease6 l
+            WHERE l.address = c.address
+              AND l.state != 2
+              AND (l.expire > now() OR l.valid_lifetime = 0xFFFFFFFF)
+        );
+
+    DROP TEMPORARY TABLE _flq6_candidates;
+
     -- Update the modification time in the flq_pool row.
     UPDATE flq_pool6 SET modification_ts = now()
         WHERE (start_address = p_start_address AND end_address = p_end_address);