Changeset 24637
- Timestamp:
- Jul 1, 2009, 5:21:32 PM (17 years ago)
- Location:
- trunk/Nebulous-Server
- Files:
-
- 4 edited
-
Changes (modified) (1 diff)
-
lib/Nebulous/Server.pm (modified) (4 diffs)
-
lib/Nebulous/Server/SQL.pm (modified) (6 diffs)
-
t/09_server_delete_instance.t (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Nebulous-Server/Changes
r24558 r24637 31 31 - change Nebulous::Server->find_objects() to return dirs and to sort it's 32 32 output 33 - add the ability to delete a storage object when it has instances that are 34 offline 33 35 34 36 0.16 -
trunk/Nebulous-Server/lib/Nebulous/Server.pm
r24607 r24637 56 56 my ($config) = @_; 57 57 58 # log4perl is not ava liable until we call init()58 # log4perl is not available until we call init() 59 59 Nebulous::Server::Log->init($config); 60 60 my $log = Log::Log4perl::get_logger( "Nebulous::Server" ); … … 1622 1622 TRANS: while (1) { 1623 1623 eval { 1624 my $instances; 1624 my $total; 1625 my $available; 1625 1626 my $so_id; 1626 1627 my $ins_id; … … 1636 1637 my $record = $query->fetchrow_hashref; 1637 1638 $so_id = $record->{ 'so_id' }; 1638 $instances = $record->{ 'count(ins_id)' }; 1639 $total = $record->{ 'total' }; 1640 $available = $record->{ 'available' }; 1639 1641 $query->finish; 1640 1642 } … … 1664 1666 die( "affected row count is $rows instead of 1" ); 1665 1667 } 1666 } 1667 1668 # if we just deleted the last instance associated with a storage object 1669 # remove it too 1670 if ( $instances == 1 ) { 1668 1669 } 1670 1671 # if we just deleted the last 'available' instance associated with 1672 # a storage object remove it too 1673 if ( $available == 1 ) { 1671 1674 # remove key from cache 1672 1675 $self->cache->delete($key->path) if defined $self->cache; 1673 1676 1674 # we just removed the last instance 1677 # record the path of the innaccesible files for deferred 1678 # deletion 1679 { 1680 my $query = $db->prepare_cached( $sql->copy_instances_to_deleted ); 1681 $query->execute( $so_id ); 1682 } 1683 # remove all instances... not strictly nessicary as the delete 1684 # from storage_object should cascade but the fkey was specified 1685 # without the cascade 1686 { 1687 my $query = $db->prepare_cached( $sql->delete_instance_by_so_id ); 1688 $query->execute( $so_id ); 1689 } 1690 1691 # delete the storage object, remaining instances should be 1692 # removed via cascading delete 1675 1693 my $query = $db->prepare_cached( $sql->delete_object ); 1676 1694 my $rows = $query->execute( $so_id ); -
trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm
r24609 r24637 180 180 WHERE ins_id = ? 181 181 }, 182 delete_instance_by_so_id => qq{ 183 DELETE FROM instance 184 WHERE so_id = ? 185 }, 182 186 get_object_from_uri => qq{ 183 187 SELECT so_id … … 198 202 }, 199 203 get_instance_count_by_ext_id => qq{ 200 SELECT count(ins_id), so_id 204 SELECT 205 so_id, 206 count(ins_id) as total, 207 sum(available) as available 201 208 FROM instance 202 209 JOIN storage_object 203 210 USING(so_id) 211 LEFT JOIN mountedvol 212 USING(vol_id) 204 213 WHERE 205 214 ext_id = ? 206 215 GROUP BY so_id 216 }, 217 copy_instances_to_deleted => qq{ 218 INSERT INTO deleted 219 SELECT NULL, vol_id, uri 220 FROM instance 221 WHERE 222 so_id = ? 207 223 }, 208 224 get_object_instances => qq{ … … 432 448 DROP TABLE IF EXISTS log; 433 449 DROP TABLE IF EXISTS directory; 434 DROP PROCEDURE IF EXISTS getmountedvol;450 DROP TABLE IF EXISTS deleted; 435 451 SET FOREIGN_KEY_CHECKS=1 436 452 END 453 #DROP PROCEDURE IF EXISTS getmountedvol; 437 454 $sql{get_db_clear} = \@clear; 438 455 } … … 451 468 452 469 1; 470 471 # ### 472 # 473 # CREATE PROCEDURE getmountedvol() DETERMINISTIC 474 # BEGIN 475 # DECLARE done BOOLEAN DEFAULT FALSE; 476 # DECLARE vol_idvar INT; 477 # DECLARE namevar VARCHAR(255); 478 # DECLARE hostvar VARCHAR(255); 479 # DECLARE pathvar VARCHAR(255); 480 # DECLARE allocatevar BOOLEAN; 481 # DECLARE availablevar BOOLEAN; 482 # DECLARE xattrvar BOOLEAN; 483 # DECLARE trans_level VARCHAR(255); 484 # DECLARE key_checks BOOLEAN; 485 # DECLARE cur1 CURSOR FOR SELECT vol_id, name, host, path, allocate, available, xattr FROM myvolume; 486 # DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE; 487 # 488 # -- store the okey checking state 489 # -- SELECT @@FOREIGN_KEY_CHECKS INTO key_checks; 490 # -- disable foregin check checks to prevent deadlocks on the mountedvol table 491 # -- SET FOREIGN_KEY_CHECKS=0; 492 # 493 # -- make sure the temp table does not already exist... this can happy if the 494 # -- stored proc fails for some reason 495 # DROP TABLE IF EXISTS myvolume; 496 # CREATE TEMPORARY TABLE myvolume LIKE volume; 497 # INSERT INTO myvolume SELECT * FROM volume; 498 # 499 # -- store the current transaction level 500 # -- SELECT @@session.tx_isolation INTO trans_level; 501 # -- set trans level to repeatable-read so the volume table does not change 502 # -- out from under our cursor 503 # -- SET @@session.tx_isolation = 'REPEATABLE-READ'; 504 # 505 # -- iterate over the volume table finding the coresponding entry in the 506 # -- mount table and inserting union of the volume & mount row into the 507 # -- mountedvol table 508 # OPEN cur1; 509 # 510 # myloop: LOOP 511 # FETCH cur1 INTO vol_idvar, namevar, hostvar, pathvar, allocatevar, availablevar, xattrvar; 512 # IF `done` THEN LEAVE myloop; END IF; 513 # REPLACE INTO mountedvol 514 # SELECT mountpoint, total, used, vol_idvar, namevar, hostvar, pathvar, allocatevar, availablevar, xattrvar 515 # FROM 516 # (SELECT *, INSTR(pathvar, mountpoint) = 1 as substring 517 # FROM mount 518 # HAVING substring = 1 519 # ORDER BY substring DESC, LENGTH(mountpoint) DESC 520 # LIMIT 1) as bar; 521 # END LOOP myloop; 522 # 523 # CLOSE cur1; 524 # 525 # -- restore the original transaction level 526 # -- SET @@session.tx_isolation = trans_level; 527 # 528 # -- restore the original key checking state 529 # -- SET @@FOREIGN_KEY_CHECKS = key_checks; 530 # 531 # DROP TABLE IF EXISTS myvolume; 532 # 533 # -- SET FOREIGN_KEY_CHECKS=1; 534 # 535 # COMMIT; 536 # END 453 537 454 538 __DATA__ … … 568 652 ins_id BIGINT NOT NULL AUTO_INCREMENT, 569 653 so_id BIGINT NOT NULL, 570 FOREIGN KEY(so_id) REFERENCES storage_object(so_id) ,654 FOREIGN KEY(so_id) REFERENCES storage_object(so_id) ON DELETE CASCADE, 571 655 vol_id INT NOT NULL, 572 656 FOREIGN KEY(vol_id) REFERENCES volume(vol_id), … … 593 677 ### 594 678 595 CREATE PROCEDURE getmountedvol() DETERMINISTIC 596 BEGIN 597 DECLARE done BOOLEAN DEFAULT FALSE; 598 DECLARE vol_idvar INT; 599 DECLARE namevar VARCHAR(255); 600 DECLARE hostvar VARCHAR(255); 601 DECLARE pathvar VARCHAR(255); 602 DECLARE allocatevar BOOLEAN; 603 DECLARE availablevar BOOLEAN; 604 DECLARE xattrvar BOOLEAN; 605 DECLARE trans_level VARCHAR(255); 606 DECLARE key_checks BOOLEAN; 607 DECLARE cur1 CURSOR FOR SELECT vol_id, name, host, path, allocate, available, xattr FROM myvolume; 608 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE; 609 610 -- store the okey checking state 611 -- SELECT @@FOREIGN_KEY_CHECKS INTO key_checks; 612 -- disable foregin check checks to prevent deadlocks on the mountedvol table 613 -- SET FOREIGN_KEY_CHECKS=0; 614 615 -- make sure the temp table does not already exist... this can happy if the 616 -- stored proc fails for some reason 617 DROP TABLE IF EXISTS myvolume; 618 CREATE TEMPORARY TABLE myvolume LIKE volume; 619 INSERT INTO myvolume SELECT * FROM volume; 620 621 -- store the current transaction level 622 -- SELECT @@session.tx_isolation INTO trans_level; 623 -- set trans level to repeatable-read so the volume table does not change 624 -- out from under our cursor 625 -- SET @@session.tx_isolation = 'REPEATABLE-READ'; 626 627 -- iterate over the volume table finding the coresponding entry in the 628 -- mount table and inserting union of the volume & mount row into the 629 -- mountedvol table 630 OPEN cur1; 631 632 myloop: LOOP 633 FETCH cur1 INTO vol_idvar, namevar, hostvar, pathvar, allocatevar, availablevar, xattrvar; 634 IF `done` THEN LEAVE myloop; END IF; 635 REPLACE INTO mountedvol 636 SELECT mountpoint, total, used, vol_idvar, namevar, hostvar, pathvar, allocatevar, availablevar, xattrvar 637 FROM 638 (SELECT *, INSTR(pathvar, mountpoint) = 1 as substring 639 FROM mount 640 HAVING substring = 1 641 ORDER BY substring DESC, LENGTH(mountpoint) DESC 642 LIMIT 1) as bar; 643 END LOOP myloop; 644 645 CLOSE cur1; 646 647 -- restore the original transaction level 648 -- SET @@session.tx_isolation = trans_level; 649 650 -- restore the original key checking state 651 -- SET @@FOREIGN_KEY_CHECKS = key_checks; 652 653 DROP TABLE IF EXISTS myvolume; 654 655 -- SET FOREIGN_KEY_CHECKS=1; 656 657 COMMIT; 658 END 679 CREATE TABLE deleted ( 680 timestamp TIMESTAMP, 681 vol_id INT NOT NULL, 682 uri VARCHAR(255) NOT NULL, 683 PRIMARY KEY(timestamp), 684 KEY(vol_id), 685 KEY(uri) 686 ) ENGINE=innodb DEFAULT CHARSET=latin1; -
trunk/Nebulous-Server/t/09_server_delete_instance.t
r24356 r24637 8 8 use warnings FATAL => qw( all ); 9 9 10 use Test::More tests => 8;10 use Test::More tests => 11; 11 11 12 12 use lib qw( ./t ./lib ); … … 20 20 dbpasswd => $NEB_PASS, 21 21 ); 22 23 use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS; 22 24 23 25 Test::Nebulous->setup; … … 44 46 45 47 ok($neb->delete_instance($key, $uri2), "delete instance"); 48 49 eval { 50 $neb->find_instances($key); 51 }; 52 like($@, qr/is valid object key/, "storage object was deleted"); 53 } 54 55 Test::Nebulous->setup; 56 57 { 58 my $key = "foo"; 59 my $uri1 = $neb->create_object($key, 'node01'); 60 my $uri2 = $neb->replicate_object($key, 'node2'); 61 62 # make one of the instances unavailable 63 my $dbh = test_dbh(); 64 $dbh->do("UPDATE mountedvol SET available = 0 WHERE name = 'node01'"); 65 66 ok($neb->delete_instance($key, $uri2), "delete instance"); 67 68 expected_dataset_ok( 69 deleted => [vol_id => 1, uri => $uri1], 70 ); 46 71 47 72 eval {
Note:
See TracChangeset
for help on using the changeset viewer.
