Bug #9486 can't perform multi-update in stored procedure
| Submitted: | 30 Mar 2005 13:58 | Modified: | 14 Jun 2005 7:18 |
|---|---|---|---|
| Reporter: | Dmitry L | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server | Severity: | S3 (Non-critical) |
| Version: | 5.0.3 | OS: | Windows (Win2k) |
| Assigned to: | Dmitry Lenev | CPU Architecture: | Any |
[9 Apr 2005 12:05]
Dmitry Lenev
Please also note that second invocation of updateTitles() will block current connection...
[14 Apr 2005 4:51]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/24000
[15 Apr 2005 16:30]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/24057
[22 Apr 2005 8:32]
Dmitry Lenev
Fixed in 5.0.5
[26 Apr 2005 3:10]
Paul DuBois
Noted in 5.0.5 changelog.
[14 Jun 2005 0:12]
Peter Brawley
This bug persists in 5.0.6, as the following script shows:
CREATE TABLE airports (
code char(3) NOT NULL,
city char(100) default NULL,
latitude float NOT NULL,
longitude float NOT NULL,
PRIMARY KEY (code)
) ENGINE=MyISAM;
INSERT INTO airports VALUES ('JFK', 'New York, NY', 40.75, -73.97);
INSERT INTO airports VALUES ('LAX', 'Los Angeles, CA', 34.05, -118.22);
INSERT INTO airports VALUES ('LHR', 'London, England', 51.5, -0.45);
INSERT INTO airports VALUES ('HEL', 'Helsinki, Finland', 60.17, 24.97);
INSERT INTO airports VALUES ('CDG', 'Paris, France', 48.86, 2.33);
INSERT INTO airports VALUES ('STL', 'St Louis, MO', 38.63, -90.2);
INSERT INTO airports VALUES ('ARN', 'Stockholm, Sweden', 59.33, 18.05);
-- Workaround for another bug
SET GLOBAL log_bin_trust_routine_creators=TRUE;
DROP FUNCTION IF EXISTS GeoDistKM;
DELIMITER |
CREATE FUNCTION GeoDistKM( lat1 FLOAT, lon1 FLOAT, lat2 FLOAT, lon2 FLOAT ) RETURNS float
BEGIN
DECLARE pi, q1, q2, q3 FLOAT;
DECLARE rads FLOAT DEFAULT 0;
SET pi = PI();
SET lat1 = lat1 * pi / 180;
SET lon1 = lon1 * pi / 180;
SET lat2 = lat2 * pi / 180;
SET lon2 = lon2 * pi / 180;
SET q1 = COS(lon1-lon2);
SET q2 = COS(lat1-lat2);
SET q3 = COS(lat1+lat2);
SET rads = ACOS( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) );
RETURN 6378.388 * rads;
END;
|
DELIMITER ;
CREATE TABLE flights (
id INT PRIMARY KEY AUTO_INCREMENT,
depart CHAR(3),
arrive CHAR(3),
distance DECIMAL(10,2),
direction DECIMAL(10,2)
) ENGINE=MYISAM;
INSERT INTO flights
SELECT
NULL,
depart.code,
arrive.code,
ROUND(GeoDistKM(depart.latitude,depart.longitude,arrive.latitude,arrive.longitude),2) AS Km,
ROUND(DEGREES(ATAN(arrive.latitude-depart.latitude,arrive.longitude-depart.longitude)),2)
FROM airports AS depart
INNER JOIN airports AS arrive ON depart.code <> arrive.code
HAVING Km <= 6000;
CREATE TABLE routes (
id INT PRIMARY KEY AUTO_INCREMENT,
depart CHAR(3),
arrive CHAR(3),
hops SMALLINT,
route CHAR(50),
distance DECIMAL(10,2),
direction DECIMAL(10,2)
) ENGINE=MYISAM;
CREATE OR REPLACE VIEW nexthops AS
SELECT
routes.depart,
flights.arrive,
routes.hops+1 AS hops,
CONCAT(routes.route, ',', flights.arrive) AS route,
MIN(routes.distance + flights.distance) AS distance,
routes.direction
FROM routes INNER JOIN flights
ON routes.arrive = flights.depart
AND LOCATE(flights.arrive,routes.route) = 0
WHERE flights.direction+360>routes.direction+270
AND flights.direction+360<routes.direction+450
GROUP BY depart,arrive;
SET GLOBAL log_bin_trust_routine_creators=TRUE;
DROP PROCEDURE IF EXISTS BuildRoutes;
DELIMITER |
CREATE PROCEDURE BuildRoutes()
BEGIN
DECLARE rows INT DEFAULT 0;
TRUNCATE routes;
-- STEP 1, LISTING 5: SEED ROUTES WITH 1-HOP FLIGHTS
INSERT INTO routes
SELECT
NULL,
depart,
arrive,
1,
CONCAT(depart,',',arrive),
distance,
direction
FROM flights;
SET rows = ROW_COUNT();
WHILE (rows > 0) DO
-- STEP 2, LISTING 8: ADD NEXT SET OF ROUTES
INSERT INTO routes
SELECT
NULL,
nexthops.depart,
nexthops.arrive,
nexthops.hops,
nexthops.route,
nexthops.distance,
nexthops.direction
FROM nexthops
LEFT JOIN routes ON nexthops.depart = routes.depart
AND nexthops.arrive = routes.arrive
WHERE routes.depart IS NULL AND routes.arrive IS NULL;
SET rows = ROW_COUNT();
END WHILE;
END;
|
DELIMITER ;
ERROR 1099 (HY000): Table 'routes' was locked with a READ lock and can't be updated
[14 Jun 2005 7:18]
Dmitry Lenev
Hi, Peter! Original problem mentioned in this bug report was impossibility to perform multi-update in stored procedure due to problem with table locking (I have updated synopsis to clarify this). After investigating your issue I think that your problem has nothing to do with original one so it should be reported and handled separately. And as I've noticed you already have done that! :) Thank you!
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.041 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: Can't perform update inside stored procedure: Error is: "Table 'op' was locked with a READ lock and can't be updated" How to repeat: here's procedure: DELIMITER $$ DROP PROCEDURE IF EXISTS `parallax_kernel`.`updateTitles`$$ CREATE PROCEDURE `parallax_kernel`.`updateTitles`(OUT affected INT) BEGIN UPDATE objects_path op, objects_hier oh SET op.title = oh.title WHERE op.pid = oh.id AND op.map = oh.map; SELECT ROW_COUNT() INTO affected; END$$ DELIMITER ; Tables: CREATE TABLE `objects_path` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`map`,`level`), KEY `pid` (`pid`), KEY `level` (`level`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `objects_hier` ( `id` int(10) unsigned NOT NULL auto_increment, `pid` int(10) unsigned NOT NULL default '0', `flags_0` int(10) unsigned NOT NULL default '0', `flags_1` int(10) unsigned NOT NULL default '0', `flags_2` int(10) unsigned NOT NULL default '0', `proto` smallint(6) unsigned NOT NULL default '0', `sort` smallint(6) NOT NULL default '0', `template` int(10) unsigned default NULL, `map` smallint(6) unsigned NOT NULL default '0', `mapped_from` smallint(6) unsigned default NULL, `lnk4` int(10) unsigned default NULL, `crt` double(15,4) unsigned NOT NULL default '0.0000', `mdf` double(15,4) unsigned NOT NULL default '0.0000', `path` bigint(20) unsigned default NULL, `owner` int(10) unsigned default NULL, `size` int(10) unsigned NOT NULL default '100', `title` varchar(255) default NULL, `remark` varchar(255) default NULL, `xml` mediumtext, PRIMARY KEY (`id`,`map`), KEY `proto` (`proto`), KEY `title` (`title`), KEY `pid` (`pid`), KEY `id` (`id`,`mapped_from`), KEY `lnk4` (`lnk4`,`map`), KEY `sort` (`sort`), KEY `path` (`path`), KEY `owner` (`owner`), KEY `size` (`size`), KEY `template` (`template`,`map`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Call is: call updateTitles(@a); There are no active locks and opened transactions on the server and call is done by @root