Changeset 23537
- Timestamp:
- Mar 25, 2009, 3:49:36 PM (17 years ago)
- Location:
- branches/neb_distrib_20081210/Nebulous-Server
- Files:
-
- 5 deleted
- 11 edited
- 1 copied
-
. (modified) (1 prop)
-
.cvsignore (deleted)
-
Changes (modified) (1 diff)
-
MANIFEST (modified) (1 diff)
-
bin/neb-admin (modified) (5 diffs)
-
bin/neb-voladd (modified) (2 diffs)
-
docs/c_api.h (deleted)
-
docs/install.txt (copied) (copied from trunk/Nebulous-Server/docs/install.txt )
-
docs/setup.txt (deleted)
-
docs/tmp.txt (deleted)
-
lib/Nebulous/Server.pm (modified) (10 diffs)
-
lib/Nebulous/Server/Config.pm (modified) (1 diff)
-
lib/Nebulous/Server/Log.pm (modified) (1 diff)
-
lib/Nebulous/Server/SQL.pm (modified) (1 diff)
-
t/.cvsignore (deleted)
-
t/02_server_setup.t (modified) (1 diff)
-
t/10_server_is_valid_volume_name.t (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/neb_distrib_20081210/Nebulous-Server
-
Property svn:mergeinfo
set to
/trunk/Nebulous-Server merged eligible
-
Property svn:mergeinfo
set to
-
branches/neb_distrib_20081210/Nebulous-Server/Changes
r20155 r23537 1 1 Revision history for Nebulous 2 3 0.17 4 - retry database transactions when a deadlock is detected 2 5 3 6 0.16 -
branches/neb_distrib_20081210/Nebulous-Server/MANIFEST
r20989 r23537 10 10 bin/neb-voladd 11 11 bin/nebdiskd 12 docs/c_api.h13 12 docs/database_setup.txt 14 13 docs/design.txt 14 docs/install.txt 15 15 docs/requirements.txt 16 docs/setup.txt17 docs/tmp.txt18 16 examples/Makefile 19 17 examples/nebexample.c -
branches/neb_distrib_20081210/Nebulous-Server/bin/neb-admin
r20202 r23537 23 23 $dbpass, 24 24 $dbuser, 25 $so_id_start, 26 $so_id_range, 25 27 $limit, 26 28 $pending, … … 41 43 'pendingreplicate|r' => \$pending, 42 44 'pendingremoval' => \$removal, 45 'so_id_start=i' => \$so_id_start, 46 'so_id_range=i' => \$so_id_range, 43 47 'limit|l=i' => \$limit, 44 48 'verbose|v' => \$verbose, … … 58 62 59 63 # check to make sure that only one instance of neb-admin is running 64 # XXX this implies we should move pending replicate elsewhere 60 65 my $pidfile = '/var/tmp/neb-admin'; 61 66 # abort if an instance is already running … … 91 96 $dbh->do("INSERT INTO myvolume SELECT * FROM volume"); 92 97 98 if (not defined $so_id_start) { $so_id_start = 0; } 99 if (not defined $so_id_range) { $so_id_range = 100000; } 100 my $so_id_end = $so_id_start + $so_id_range; 101 102 # XXX check if so_id_start is beyond MAX(so_id): if so, exit with exit status 10 103 { 104 my $query = $dbh->prepare("SELECT MAX(so_id) from storage_object"); 105 $query->execute; 106 my $answer = $query->fetchrow_arrayref; 107 my $max_so_id = $$answer[0]; 108 $query->finish; 109 110 if ($so_id_start > $max_so_id) { 111 print STDERR "at end of so_id range, reset please\n"; 112 exit 10; 113 } 114 } 115 93 116 my $query = $dbh->prepare( 94 117 " SELECT … … 111 134 USING(vol_id) 112 135 WHERE mymountedvol.available = 1 113 -- WHERE storage_object_xattr.name = 'user.copies' 136 AND storage_object_xattr.name = 'user.copies' 137 AND storage_object.so_id >= $so_id_start 138 AND storage_object.so_id < $so_id_end 114 139 GROUP BY so_id 115 140 HAVING available_instances < instances OR instances < copies -
branches/neb_distrib_20081210/Nebulous-Server/bin/neb-voladd
r19797 r23537 79 79 =head1 SYNOPSIS 80 80 81 neb-voladd --v olume <volumename> --uri <volume uri>81 neb-voladd --vname <volume name> --vhost <host name> --uri <volume uri> 82 82 [--db <database>] [--user <username>] [--pass <password>] [--host <hostname] 83 83 … … 92 92 =over 4 93 93 94 =item * --v olume <volume name>94 =item * --vname <volume name> 95 95 96 96 Symbolic name of volume being added. 97 98 =item * --vhost <host name> 99 100 Name of the host that containes the C<URI> of the volume being added. 97 101 98 102 =item * --uri|-u <volume uri> -
branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server.pm
r20989 r23537 1 1 # Copyright (c) 2004-2008 Joshua Hoblitt 2 2 # 3 # $Id: Server.pm,v 1.9 3.6.1 2008-12-14 22:52:37eugene Exp $3 # $Id: Server.pm,v 1.96 2008-12-14 22:54:25 eugene Exp $ 4 4 5 5 package Nebulous::Server; … … 176 176 177 177 my $uri; 178 eval { 179 { 180 # create storage_object 181 my $query = $db->prepare_cached( $sql->new_object ); 182 $query->execute('NULL', $key->path); 183 } 184 185 my $so_id; 186 { 187 # get object ID 188 my $query = $db->prepare_cached( $sql->last_insert_id ); 189 $query->execute; 190 ($so_id) = $query->fetchrow_array; 191 # XXX finish seems to be required when using LAST_INSERT_ID() or we 192 # get a warning about the stmt handling still be active the next 193 # time LAST_INSERT_ID() is invoked 194 $query->finish; 195 } 196 197 { 198 # create storage_object_attr 199 my $query = $db->prepare_cached( $sql->new_object_attr ); 200 $query->execute($so_id); 201 } 202 203 { 204 205 # create instance with no URI 178 TRANS: while (1) { 179 eval { 180 { 181 # create storage_object 182 my $query = $db->prepare_cached( $sql->new_object ); 183 $query->execute('NULL', $key->path); 184 } 185 186 my $so_id; 187 { 188 # get object ID 189 my $query = $db->prepare_cached( $sql->last_insert_id ); 190 $query->execute; 191 ($so_id) = $query->fetchrow_array; 192 # XXX finish seems to be required when using LAST_INSERT_ID() or we 193 # get a warning about the stmt handling still be active the next 194 # time LAST_INSERT_ID() is invoked 195 $query->finish; 196 } 197 198 { 199 # create storage_object_attr 200 my $query = $db->prepare_cached( $sql->new_object_attr ); 201 $query->execute($so_id); 202 } 203 204 { 205 206 # create instance with no URI 206 207 # my $query = $db->prepare_cached( $sql->new_instance ); 207 my $query = $db->prepare_cached( $sql->new_object_instance );208 $query->execute($vol_id);209 }210 211 my $ins_id;212 {213 # get instance ID214 my $query = $db->prepare_cached( $sql->last_insert_id );215 $query->execute;216 ($ins_id) = $query->fetchrow_array;217 # XXX finish seems to be required when using LAST_INSERT_ID() or we218 # get a warning about the stmt handling still be active the next219 # time LAST_INSERT_ID() is invoked220 $query->finish;221 }222 223 # Unfortunately, since we want to use the instance row's ID as part of the224 # actual on disk file name we can't try to create the file until after225 # we've create both a new storage_storage object and instance.226 227 # TODO add some stuff here to retry if unsucessful228 $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr);229 $log->debug("created $uri on volume ID: $vol_id");230 231 {232 # update the instance with URI & vol_id that the file is on233 my $query = $db->prepare_cached( $sql->update_instance_uri );234 # vol_id, uri, ins_id235 $query->execute($vol_id, "$uri", $ins_id);236 }237 238 $db->commit;239 $log->debug("commit");240 };241 if ($@) {208 my $query = $db->prepare_cached( $sql->new_object_instance ); 209 $query->execute($vol_id); 210 } 211 212 my $ins_id; 213 { 214 # get instance ID 215 my $query = $db->prepare_cached( $sql->last_insert_id ); 216 $query->execute; 217 ($ins_id) = $query->fetchrow_array; 218 # XXX finish seems to be required when using LAST_INSERT_ID() or we 219 # get a warning about the stmt handling still be active the next 220 # time LAST_INSERT_ID() is invoked 221 $query->finish; 222 } 223 224 # Unfortunately, since we want to use the instance row's ID as part of the 225 # actual on disk file name we can't try to create the file until after 226 # we've create both a new storage_storage object and instance. 227 228 # TODO add some stuff here to retry if unsucessful 229 $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr); 230 $log->debug("created $uri on volume ID: $vol_id"); 231 232 { 233 # update the instance with URI & vol_id that the file is on 234 my $query = $db->prepare_cached( $sql->update_instance_uri ); 235 # vol_id, uri, ins_id 236 $query->execute($vol_id, "$uri", $ins_id); 237 } 238 239 $db->commit; 240 $log->debug("commit"); 241 }; 242 if ($@) { 242 243 # and not $key->soft_volume 243 $db->rollback; 244 $log->debug("rollback"); 245 $log->logdie("error: $@"); 244 $db->rollback; 245 $log->debug("rollback"); 246 if ($@ =~ /Deadlock found/) { 247 $log->warn("database deadlock retrying transaction: $@"); 248 redo TRANS; 249 } 250 $log->logdie("error: $@"); 251 } 252 last; 246 253 } 247 254 … … 282 289 $newkey = parse_neb_key($newkey); 283 290 284 eval { 285 # rename storage_object 286 my $query = $db->prepare_cached($sql->rename_object); 287 # this SQL statment takes the new key name as the first param 288 my $rows = $query->execute($newkey->path, $key->path); 289 290 # if we affected more then one row something very bad has happened. 291 unless ($rows == 1) { 292 $query->finish; 293 $log->logdie("affected row count is $rows instead of 1"); 294 } 295 296 $db->commit; 297 $log->debug("commit"); 298 }; 299 if ($@) { 300 $db->rollback; 301 $log->debug("rollback"); 302 $log->logdie("database error: $@"); 303 } 291 TRANS: while (1) { 292 eval { 293 # rename storage_object 294 my $query = $db->prepare_cached($sql->rename_object); 295 # this SQL statment takes the new key name as the first param 296 my $rows = $query->execute($newkey->path, $key->path); 297 298 # if we affected more then one row something very bad has happened. 299 unless ($rows == 1) { 300 $query->finish; 301 $log->logdie("affected row count is $rows instead of 1"); 302 } 303 304 $db->commit; 305 $log->debug("commit"); 306 }; 307 if ($@) { 308 $db->rollback; 309 $log->debug("rollback"); 310 if ($@ =~ /Deadlock found/) { 311 $log->warn("database deadlock retrying transaction: $@"); 312 redo TRANS; 313 } 314 $log->logdie("database error: $@"); 315 } 316 last; 317 } 304 318 305 319 $log->debug("leaving"); … … 462 476 # return 1; 463 477 # } 464 478 # 479 480 # ### this block below comes from the single branch, and implements 481 # the transactions in the new way (two passes?). the above handles 482 # the case of multiple dbs 483 # 484 # TRANS: while (1) { 485 # eval { 486 # { 487 # # key1 -> key1.swap 488 # my $query = $db->prepare_cached($sql->rename_object); 489 # # this SQL statment takes the new key name as the first param 490 # my $rows = $query->execute($key1->path . ".swap", $key1->path); 491 # 492 # # if we affected more then one row something very bad has happened. 493 # unless ($rows == 1) { 494 # $query->finish; 495 # $log->logdie("affected row count is $rows instead of 1"); 496 # } 497 # } 498 # 499 # { 500 # # key2 -> key1 501 # my $query = $db->prepare_cached($sql->rename_object); 502 # # this SQL statment takes the new key name as the first param 503 # my $rows = $query->execute($key1->path, $key2->path); 504 # 505 # # if we affected more then one row something very bad has happened. 506 # unless ($rows == 1) { 507 # $query->finish; 508 # $log->logdie("affected row count is $rows instead of 1"); 509 # } 510 # } 511 # 512 # { 513 # # key1.swap -> key2 514 # my $query = $db->prepare_cached($sql->rename_object); 515 # # this SQL statment takes the new key name as the first param 516 # my $rows = $query->execute($key2->path, $key1->path . ".swap"); 517 # 518 # # if we affected more then one row something very bad has happened. 519 # unless ($rows == 1) { 520 # $query->finish; 521 # $log->logdie("affected row count is $rows instead of 1"); 522 # } 523 # } 524 # 525 # $db->commit; 526 # $log->debug("commit"); 527 # }; 528 # if ($@) { 529 # $db->rollback; 530 # $log->debug("rollback"); 531 # if ($@ =~ /Deadlock found/) { 532 # $log->warn("database deadlock retrying transaction: $@"); 533 # redo TRANS; 534 # } 535 # $log->logdie("database error: $@"); 536 # } 537 # last; 538 # } 539 # 540 # $log->debug("leaving"); 541 # 542 # return 1; 543 # } 465 544 466 545 sub replicate_object … … 527 606 528 607 my $uri; 529 eval { 530 my $so_id; 531 { 532 # verify that at least one instance is currently available 533 my $query = $db->prepare_cached( $sql->get_object_instances ); 534 my $rows = $query->execute($key->path, 1); 535 536 unless ( $rows > 0 ) { 608 TRANS: while (1) { 609 eval { 610 my $so_id; 611 { 612 # verify that at least one instance is currently available 613 my $query = $db->prepare_cached( $sql->get_object_instances ); 614 my $rows = $query->execute($key->path, 1); 615 616 unless ( $rows > 0 ) { 617 $query->finish; 618 $log->logdie( "storage object does not exist" ); 619 } 620 621 $so_id = $query->fetchrow_hashref->{ 'so_id' }; 537 622 $query->finish; 538 $log->logdie( "storage object does not exist" ); 539 } 540 541 $so_id = $query->fetchrow_hashref->{ 'so_id' }; 542 $query->finish; 543 } 544 545 { 546 my $query = $db->prepare_cached( $sql->new_instance ); 547 $query->execute($so_id, $vol_id); 548 } 549 550 my $ins_id; 551 { 552 my $query = $db->prepare_cached( $sql->last_insert_id ); 553 $query->execute(); 554 ($ins_id) = $query->fetchrow_array; 555 # XXX finish seems to be required when using LAST_INSERT_ID() or we 556 # get a warning about the stmt handling still being active the next 557 # time LAST_INSERT_ID() is invoked 558 $query->finish; 559 } 560 561 # Unfortunately, since we want to use the instance row's ID as part of 562 # the actual on disk file name we can't try to create the file until 563 # after we've create both a new storage_storage object and instance. 564 565 # TODO add some stuff here to retry if unsucessful 566 $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr); 567 568 { 569 my $query = $db->prepare_cached( $sql->update_instance_uri ); 570 # vol_id, uri, ins_id 571 $query->execute($vol_id, $uri, $ins_id); 572 } 573 574 $db->commit; 575 $log->debug("commit"); 576 }; 577 if ($@) { 578 $db->rollback; 579 # handle soft volumes 580 if (defined $vol_name and defined $key->soft_volume) { 581 $log->debug("retrying with 'any' volume"); 582 return $self->replicate_object($key->path, 'any'); 583 } 584 $log->debug("rollback"); 585 $log->logdie("error: $@"); 623 } 624 625 { 626 my $query = $db->prepare_cached( $sql->new_instance ); 627 $query->execute($so_id, $vol_id); 628 } 629 630 my $ins_id; 631 { 632 my $query = $db->prepare_cached( $sql->last_insert_id ); 633 $query->execute(); 634 ($ins_id) = $query->fetchrow_array; 635 # XXX finish seems to be required when using LAST_INSERT_ID() or we 636 # get a warning about the stmt handling still being active the next 637 # time LAST_INSERT_ID() is invoked 638 $query->finish; 639 } 640 641 # Unfortunately, since we want to use the instance row's ID as part of 642 # the actual on disk file name we can't try to create the file until 643 # after we've create both a new storage_storage object and instance. 644 645 # TODO add some stuff here to retry if unsucessful 646 $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr); 647 648 { 649 my $query = $db->prepare_cached( $sql->update_instance_uri ); 650 # vol_id, uri, ins_id 651 $query->execute($vol_id, $uri, $ins_id); 652 } 653 654 $db->commit; 655 $log->debug("commit"); 656 }; 657 if ($@) { 658 $db->rollback; 659 # handle soft volumes 660 if (defined $vol_name and defined $key->soft_volume) { 661 $log->debug("retrying with 'any' volume"); 662 return $self->replicate_object($key->path, 'any'); 663 } 664 $log->debug("rollback"); 665 if ($@ =~ /Deadlock found/) { 666 $log->warn("database deadlock retrying transaction: $@"); 667 redo TRANS; 668 } 669 $log->logdie("error: $@"); 670 } 671 last; 586 672 } 587 673 … … 624 710 my $write_lock; 625 711 626 eval { 627 { 628 # this will set update locks 629 my $query = $db->prepare_cached( $sql->get_object_locks ); 630 my $rows = $query->execute( $key->path ); 631 unless ( $rows == 1 ) { 712 TRANS: while (1) { 713 eval { 714 { 715 # this will set update locks 716 my $query = $db->prepare_cached( $sql->get_object_locks ); 717 my $rows = $query->execute( $key->path ); 718 unless ( $rows == 1 ) { 719 $query->finish; 720 $log->logdie( "storage object does not exist" ); 721 } 722 723 my $row = $query->fetchrow_hashref; 632 724 $query->finish; 633 $log->logdie( "storage object does not exist" ); 634 } 635 636 my $row = $query->fetchrow_hashref; 637 $query->finish; 638 639 $so_id = $row->{ 'so_id' }; 640 $read_lock = $row->{ 'read_lock' }; 641 $write_lock = $row->{ 'write_lock' }; 642 } 643 644 if ($type eq 'write') { 645 # can't set a write lock twice and 646 # can't set a write lock if there are read locks 647 if ($write_lock) { 648 $log->logdie("can not write lock twice -- retry"); 649 } 650 651 if ($read_lock > 0) { 652 $log->logdie("can not write lock after read lock -- retry"); 653 } 654 655 { 656 my $query = $db->prepare_cached( $sql->set_write_lock ); 657 my $rows = $query->execute($key->path); 658 659 # if we affected more then one row something very bad has happened. 660 unless ($rows == 1) { 661 $log->logdie("affected row count is $rows instead of 1"); 662 } 663 664 } 665 } elsif ($type eq 'read') { 666 # can't set a read lock if there's a write lock 667 if ($write_lock) { 668 $log->logdie("can not read lock after write lock -- retry"); 669 } 670 671 { 672 my $query = $db->prepare_cached( $sql->increment_read_lock ); 673 my $rows = $query->execute($key->path); 674 675 # if we affected more then one row something very bad has happened. 676 unless ($rows == 1) { 677 $log->logdie("affected row count is $rows instead of 1"); 678 } 679 } 680 } 681 682 $db->commit; 683 $log->debug("commit"); 684 }; 685 if ($@) { 686 $db->rollback; 687 $log->debug("rollback"); 688 $log->logdie("error: $@"); 725 726 $so_id = $row->{ 'so_id' }; 727 $read_lock = $row->{ 'read_lock' }; 728 $write_lock = $row->{ 'write_lock' }; 729 } 730 731 if ($type eq 'write') { 732 # can't set a write lock twice and 733 # can't set a write lock if there are read locks 734 if ($write_lock) { 735 $log->logdie("can not write lock twice -- retry"); 736 } 737 738 if ($read_lock > 0) { 739 $log->logdie("can not write lock after read lock -- retry"); 740 } 741 742 { 743 my $query = $db->prepare_cached( $sql->set_write_lock ); 744 my $rows = $query->execute($key->path); 745 746 # if we affected more then one row something very bad has happened. 747 unless ($rows == 1) { 748 $log->logdie("affected row count is $rows instead of 1"); 749 } 750 751 } 752 } elsif ($type eq 'read') { 753 # can't set a read lock if there's a write lock 754 if ($write_lock) { 755 $log->logdie("can not read lock after write lock -- retry"); 756 } 757 758 { 759 my $query = $db->prepare_cached( $sql->increment_read_lock ); 760 my $rows = $query->execute($key->path); 761 762 # if we affected more then one row something very bad has happened. 763 unless ($rows == 1) { 764 $log->logdie("affected row count is $rows instead of 1"); 765 } 766 } 767 } 768 769 $db->commit; 770 $log->debug("commit"); 771 }; 772 if ($@) { 773 $db->rollback; 774 $log->debug("rollback"); 775 if ($@ =~ /Deadlock found/) { 776 $log->warn("database deadlock retrying transaction: $@"); 777 redo TRANS; 778 } 779 $log->logdie("error: $@"); 780 } 781 last; 689 782 } 690 783 … … 727 820 my $write_lock; 728 821 729 eval { 730 { 731 # this will set update locks 732 my $query = $db->prepare_cached( $sql->get_object_locks ); 733 my $rows = $query->execute($key->path); 734 unless ($rows == 1) { 822 TRANS: while (1) { 823 eval { 824 { 825 # this will set update locks 826 my $query = $db->prepare_cached( $sql->get_object_locks ); 827 my $rows = $query->execute($key->path); 828 unless ($rows == 1) { 829 $query->finish; 830 $log->logdie("storage object does not exist"); 831 } 832 833 my $row = $query->fetchrow_hashref; 735 834 $query->finish; 736 $log->logdie("storage object does not exist"); 737 } 738 739 my $row = $query->fetchrow_hashref; 740 $query->finish; 741 742 $so_id = $row->{ 'so_id' }; 743 $read_lock = $row->{ 'read_lock' }; 744 $write_lock = $row->{ 'write_lock' }; 745 } 746 747 if ($type eq 'write') { 748 # can't remove a write lock if it doesn't exist 749 if ($read_lock) { 750 $log->logdie("can not have a write lock under a read lock"); 751 } 752 753 unless ($write_lock) { 754 $log->logdie("can not remove non-existant write lock"); 755 } 756 757 { 758 my $query = $db->prepare_cached( $sql->delete_write_lock ); 759 my $rows = $query->execute($key->path); 760 761 # if we affected more then one row something very bad has happened. 762 unless ($rows == 1) { 763 $log->logdie("affected row count is $rows instead of 1"); 764 } 765 } 766 } elsif ($type eq 'read') { 767 # can't remove a read lock if there's a write lock and 768 # can't remove a read lock if there aren't any 769 if ($write_lock) { 770 $log->logdie("can not have a read lock under a write lock"); 771 } 772 773 if ($read_lock == 0) { 774 $log->logdie("can not remove non-existant read lock"); 775 } 776 777 { 778 my $query = $db->prepare_cached( $sql->decrement_read_lock ); 779 my $rows = $query->execute($key->path); 780 781 # if we affected more then one row something very bad has happened. 782 unless ($rows == 1) { 783 $log->logdie("affected row count is $rows instead of 1"); 784 } 785 786 } 787 } 788 $db->commit; 789 $log->debug("commit"); 790 }; 791 if ($@) { 792 $db->rollback; 793 $log->debug("rollback"); 794 $log->logdie("error: $@"); 835 836 $so_id = $row->{ 'so_id' }; 837 $read_lock = $row->{ 'read_lock' }; 838 $write_lock = $row->{ 'write_lock' }; 839 } 840 841 if ($type eq 'write') { 842 # can't remove a write lock if it doesn't exist 843 if ($read_lock) { 844 $log->logdie("can not have a write lock under a read lock"); 845 } 846 847 unless ($write_lock) { 848 $log->logdie("can not remove non-existant write lock"); 849 } 850 851 { 852 my $query = $db->prepare_cached( $sql->delete_write_lock ); 853 my $rows = $query->execute($key->path); 854 855 # if we affected more then one row something very bad has happened. 856 unless ($rows == 1) { 857 $log->logdie("affected row count is $rows instead of 1"); 858 } 859 } 860 } elsif ($type eq 'read') { 861 # can't remove a read lock if there's a write lock and 862 # can't remove a read lock if there aren't any 863 if ($write_lock) { 864 $log->logdie("can not have a read lock under a write lock"); 865 } 866 867 if ($read_lock == 0) { 868 $log->logdie("can not remove non-existant read lock"); 869 } 870 871 { 872 my $query = $db->prepare_cached( $sql->decrement_read_lock ); 873 my $rows = $query->execute($key->path); 874 875 # if we affected more then one row something very bad has happened. 876 unless ($rows == 1) { 877 $log->logdie("affected row count is $rows instead of 1"); 878 } 879 880 } 881 } 882 $db->commit; 883 $log->debug("commit"); 884 }; 885 if ($@) { 886 $db->rollback; 887 $log->debug("rollback"); 888 if ($@ =~ /Deadlock found/) { 889 $log->warn("database deadlock retrying transaction: $@"); 890 redo TRANS; 891 } 892 $log->logdie("error: $@"); 893 } 894 last; 795 895 } 796 896 … … 835 935 $key = parse_neb_key($key); 836 936 837 eval { 838 my $query; 839 840 if ($flags eq 'create') { 841 $query = $db->prepare_cached( $sql->new_object_xattr ); 842 } else { 843 # replace 844 $query = $db->prepare_cached( $sql->replace_object_xattr ); 845 } 846 847 # name, value, ext_id 848 my $rows = $query->execute($name, $value, $key->path); 849 $query->finish; 850 851 # if we affected more then one row something very bad has happened. 852 if ($flags eq 'create') { 853 unless ($rows == 1) { 854 $log->logdie( "affected row count is $rows instead of 1" ); 855 } 856 } else { 857 # replace_object_xattr can effect either 1 or 2 rows. 2 rows in 858 # the case of a replace and 1 if the xattr didn't already exist. 859 unless ($rows == 1 or $rows == 2) { 860 $log->logdie( "affected row count is $rows instead of 2" ); 861 } 862 } 863 864 $db->commit; 865 $log->debug("commit"); 866 }; 867 if ($@) { 868 $db->rollback; 869 $log->debug("rollback"); 870 $log->logdie("database error: $@"); 937 TRANS: while (1) { 938 eval { 939 my $query; 940 941 if ($flags eq 'create') { 942 $query = $db->prepare_cached( $sql->new_object_xattr ); 943 } else { 944 # replace 945 $query = $db->prepare_cached( $sql->replace_object_xattr ); 946 } 947 948 # name, value, ext_id 949 my $rows = $query->execute($name, $value, $key->path); 950 $query->finish; 951 952 # if we affected more then one row something very bad has happened. 953 if ($flags eq 'create') { 954 unless ($rows == 1) { 955 $log->logdie( "affected row count is $rows instead of 1" ); 956 } 957 } else { 958 # replace_object_xattr can effect either 1 or 2 rows. 2 rows in 959 # the case of a replace and 1 if the xattr didn't already exist. 960 unless ($rows == 1 or $rows == 2) { 961 $log->logdie( "affected row count is $rows instead of 2" ); 962 } 963 } 964 965 $db->commit; 966 $log->debug("commit"); 967 }; 968 if ($@) { 969 $db->rollback; 970 $log->debug("rollback"); 971 if ($@ =~ /Deadlock found/) { 972 $log->warn("database deadlock retrying transaction: $@"); 973 redo TRANS; 974 } 975 $log->logdie("database error: $@"); 976 } 977 last; 871 978 } 872 979 … … 998 1105 $key = parse_neb_key($key); 999 1106 1000 eval { 1001 my $query = $db->prepare_cached( $sql->remove_object_xattr ); 1002 # ext_id, name 1003 my $rows = $query->execute($key->path, $name); 1004 $query->finish; 1005 1006 # if we affected more then one row something very bad has happened. 1007 unless ($rows == 1) { 1008 $log->logdie( "affected row count is $rows instead of 1" ); 1009 } 1010 1011 $db->commit; 1012 $log->debug("commit"); 1013 }; 1014 if ($@) { 1015 $db->rollback; 1016 $log->debug("rollback"); 1017 $log->logdie("database error: $@"); 1018 } 1107 TRANS: while (1) { 1108 eval { 1109 my $query = $db->prepare_cached( $sql->remove_object_xattr ); 1110 # ext_id, name 1111 my $rows = $query->execute($key->path, $name); 1112 $query->finish; 1113 1114 # if we affected more then one row something very bad has happened. 1115 unless ($rows == 1) { 1116 $log->logdie( "affected row count is $rows instead of 1" ); 1117 } 1118 1119 $db->commit; 1120 $log->debug("commit"); 1121 }; 1122 if ($@) { 1123 $db->rollback; 1124 $log->debug("rollback"); 1125 if ($@ =~ /Deadlock found/) { 1126 $log->warn("database deadlock retrying transaction: $@"); 1127 redo TRANS; 1128 } 1129 $log->logdie("database error: $@"); 1130 } 1131 last; 1132 } 1019 1133 1020 1134 $log->debug("leaving"); … … 1186 1300 $log->debug( "entered - @_" ); 1187 1301 1188 eval { 1189 my $so_id; 1190 my $instances; 1191 # get so_id 1192 { 1193 my $query = $db->prepare_cached( $sql->get_object_from_uri ); 1194 my $rows = $query->execute( $uri ); 1195 1196 unless ( $rows > 0 ) { 1302 TRANS: while (1) { 1303 eval { 1304 my $so_id; 1305 my $instances; 1306 # get so_id 1307 { 1308 my $query = $db->prepare_cached( $sql->get_object_from_uri ); 1309 my $rows = $query->execute( $uri ); 1310 1311 unless ( $rows > 0 ) { 1312 $query->finish; 1313 $log->logdie( "no instance is associated with uri" ); 1314 } 1315 1316 $so_id = $query->fetchrow_hashref->{ 'so_id' }; 1197 1317 $query->finish; 1198 $log->logdie( "no instance is associated with uri" ); 1199 } 1200 1201 $so_id = $query->fetchrow_hashref->{ 'so_id' }; 1202 $query->finish; 1203 1204 } 1205 1206 { 1207 my $query = $db->prepare_cached( $sql->get_instance_count ); 1208 $query->execute( $so_id ); 1209 1210 $instances = $query->fetchrow_hashref->{ 'count(ins_id)' }; 1211 $query->finish; 1212 } 1213 1214 # remove instance 1215 { 1216 my $query = $db->prepare_cached( $sql->delete_instance ); 1217 my $rows = $query->execute( $uri ); 1218 $query->finish; 1219 1220 # if we affected something other then two rows something very bad 1221 # has happened 1222 unless ( $rows == 1 ) { 1223 $log->logdie( "affected row count is $rows instead of 1" ); 1224 } 1225 } 1226 1227 # if we just deleted the last instance associated with a storage object 1228 # remove it too 1229 if ( $instances == 1 ) { 1230 # we just removed the last instance 1231 my $query = $db->prepare_cached( $sql->delete_object ); 1232 my $rows = $query->execute( $so_id ); 1233 $query->finish; 1234 1235 # TODO: this will have to be changed in order to support hardlinks 1236 unless ( $rows == 1 ) { 1237 $log->logdie( "affected row count is $rows instead of 2" ); 1238 } 1239 } 1240 1241 $db->commit; 1242 $log->debug("commit"); 1243 }; 1244 if ( $@ ) { 1245 $db->rollback; 1246 $log->debug("rollback"); 1247 $log->logdie( "database error: $@" ); 1318 1319 } 1320 1321 { 1322 my $query = $db->prepare_cached( $sql->get_instance_count ); 1323 $query->execute( $so_id ); 1324 1325 $instances = $query->fetchrow_hashref->{ 'count(ins_id)' }; 1326 $query->finish; 1327 } 1328 1329 # remove instance 1330 { 1331 my $query = $db->prepare_cached( $sql->delete_instance ); 1332 my $rows = $query->execute( $uri ); 1333 $query->finish; 1334 1335 # if we affected something other then two rows something very bad 1336 # has happened 1337 unless ( $rows == 1 ) { 1338 $log->logdie( "affected row count is $rows instead of 1" ); 1339 } 1340 } 1341 1342 # if we just deleted the last instance associated with a storage object 1343 # remove it too 1344 if ( $instances == 1 ) { 1345 # we just removed the last instance 1346 my $query = $db->prepare_cached( $sql->delete_object ); 1347 my $rows = $query->execute( $so_id ); 1348 $query->finish; 1349 1350 # TODO: this will have to be changed in order to support hardlinks 1351 unless ( $rows == 1 ) { 1352 $log->logdie( "affected row count is $rows instead of 2" ); 1353 } 1354 } 1355 1356 $db->commit; 1357 $log->debug("commit"); 1358 }; 1359 if ( $@ ) { 1360 $db->rollback; 1361 $log->debug("rollback"); 1362 if ($@ =~ /Deadlock found/) { 1363 $log->warn("database deadlock retrying transaction: $@"); 1364 redo TRANS; 1365 } 1366 $log->logdie( "database error: $@" ); 1367 } 1368 last; 1248 1369 } 1249 1370 -
branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/Config.pm
r20989 r23537 1 1 # Copyright (C) 2005 Joshua Hoblitt 2 2 # 3 # $Id: Config.pm,v 1. 3.22.1 2008-12-14 22:52:37eugene Exp $3 # $Id: Config.pm,v 1.5 2008-12-14 22:54:25 eugene Exp $ 4 4 5 5 package Nebulous::Server::Config; -
branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/Log.pm
r20989 r23537 1 1 # Copyright (c) 2004 Joshua Hoblitt 2 2 # 3 # $Id: Log.pm,v 1. 7.22.1 2008-12-14 22:52:37eugene Exp $3 # $Id: Log.pm,v 1.9 2008-12-14 22:54:25 eugene Exp $ 4 4 5 5 package Nebulous::Server::Log; -
branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/SQL.pm
r20989 r23537 1 1 # Copyright (c) 2004 Joshua Hoblitt 2 2 # 3 # $Id: SQL.pm,v 1.7 5.6.1 2008-12-14 22:52:37eugene Exp $3 # $Id: SQL.pm,v 1.78 2008-12-14 22:54:25 eugene Exp $ 4 4 5 5 package Nebulous::Server::SQL; -
branches/neb_distrib_20081210/Nebulous-Server/t/02_server_setup.t
r20989 r23537 3 3 # Copryight (C) 2004-2005 Joshua Hoblitt 4 4 # 5 # $Id: 02_server_setup.t,v 1. 6.22.1 2008-12-14 22:52:37eugene Exp $5 # $Id: 02_server_setup.t,v 1.8 2008-12-14 22:54:25 eugene Exp $ 6 6 7 7 use strict; -
branches/neb_distrib_20081210/Nebulous-Server/t/10_server_is_valid_volume_name.t
r20989 r23537 3 3 # Copryight (C) 2004-2005 Joshua Hoblitt 4 4 # 5 # $Id: 10_server_is_valid_volume_name.t,v 1. 5.22.1 2008-12-14 22:52:37eugene Exp $5 # $Id: 10_server_is_valid_volume_name.t,v 1.7 2008-12-14 22:54:25 eugene Exp $ 6 6 7 7 use strict;
Note:
See TracChangeset
for help on using the changeset viewer.
